You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2015/08/04 16:25:41 UTC
[01/18] olingo-odata4 git commit: [OLINGO-735] Replaced
'*Builder.reflection*' were possible
Repository: olingo-odata4
Updated Branches:
refs/heads/OLINGO-640 5b99eb7b6 -> db0b9d39d
[OLINGO-735] Replaced '*Builder.reflection*' were possible
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/1ebbbc36
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/1ebbbc36
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/1ebbbc36
Branch: refs/heads/OLINGO-640
Commit: 1ebbbc3698de644c097efe44472130ef248baa92
Parents: 9674aae
Author: mibo <mi...@apache.org>
Authored: Wed Jul 22 10:15:29 2015 +0200
Committer: mibo <mi...@apache.org>
Committed: Wed Jul 22 10:15:29 2015 +0200
----------------------------------------------------------------------
.../olingo/client/api/data/ServiceDocument.java | 4 +-
.../client/core/data/ServiceDocumentImpl.java | 53 +++++++++++++++----
.../core/data/ServiceDocumentItemImpl.java | 32 ++++++++----
.../client/core/domain/ClientPropertyImpl.java | 39 ++++++++++----
.../client/core/domain/ClientValuableImpl.java | 27 ++++++----
.../commons/api/edm/FullQualifiedName.java | 32 +++++++++---
.../apache/olingo/commons/api/edm/geo/SRID.java | 54 ++++++++++++++------
7 files changed, 178 insertions(+), 63 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1ebbbc36/lib/client-api/src/main/java/org/apache/olingo/client/api/data/ServiceDocument.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/data/ServiceDocument.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/data/ServiceDocument.java
index 47cbf67..5b6ed0d 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/data/ServiceDocument.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/data/ServiceDocument.java
@@ -18,15 +18,13 @@
*/
package org.apache.olingo.client.api.data;
-import org.apache.olingo.client.api.domain.ClientServiceDocument;
-
import java.net.URI;
import java.util.List;
/**
* REST resource for an <tt>ODataServiceDocument</tt>.
*
- * @see ClientServiceDocument
+ * @see org.apache.olingo.client.api.domain.ClientServiceDocument
*/
public interface ServiceDocument {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1ebbbc36/lib/client-core/src/main/java/org/apache/olingo/client/core/data/ServiceDocumentImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/ServiceDocumentImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/ServiceDocumentImpl.java
index ec10e9d..4bf6a09 100755
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/ServiceDocumentImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/ServiceDocumentImpl.java
@@ -22,15 +22,11 @@ import java.net.URI;
import java.util.ArrayList;
import java.util.List;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.olingo.client.api.data.ServiceDocument;
import org.apache.olingo.client.api.data.ServiceDocumentItem;
import org.apache.olingo.commons.api.Constants;
-public class ServiceDocumentImpl implements ServiceDocument {
+public final class ServiceDocumentImpl implements ServiceDocument {
private String title;
@@ -125,17 +121,56 @@ public class ServiceDocumentImpl implements ServiceDocument {
}
@Override
- public boolean equals(final Object obj) {
- return EqualsBuilder.reflectionEquals(this, obj);
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ ServiceDocumentImpl that = (ServiceDocumentImpl) o;
+
+ if (title != null ? !title.equals(that.title) : that.title != null) {
+ return false;
+ }
+ if (entitySets != null ? !entitySets.equals(that.entitySets) : that.entitySets != null) {
+ return false;
+ }
+ if (functionImports != null ? !functionImports.equals(that.functionImports) : that.functionImports != null) {
+ return false;
+ }
+ if (singletons != null ? !singletons.equals(that.singletons) : that.singletons != null) {
+ return false;
+ }
+ if (relatedServiceDocuments != null ?
+ !relatedServiceDocuments.equals(that.relatedServiceDocuments) : that.relatedServiceDocuments != null) {
+ return false;
+ }
+ return !(metadata != null ? !metadata.equals(that.metadata) : that.metadata != null);
+
}
@Override
public int hashCode() {
- return HashCodeBuilder.reflectionHashCode(this);
+ int result = title != null ? title.hashCode() : 0;
+ result = 31 * result + (entitySets != null ? entitySets.hashCode() : 0);
+ result = 31 * result + (functionImports != null ? functionImports.hashCode() : 0);
+ result = 31 * result + (singletons != null ? singletons.hashCode() : 0);
+ result = 31 * result + (relatedServiceDocuments != null ? relatedServiceDocuments.hashCode() : 0);
+ result = 31 * result + (metadata != null ? metadata.hashCode() : 0);
+ return result;
}
@Override
public String toString() {
- return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return "ServiceDocumentImpl{" +
+ "title='" + title + '\'' +
+ ", entitySets=" + entitySets +
+ ", functionImports=" + functionImports +
+ ", singletons=" + singletons +
+ ", relatedServiceDocuments=" + relatedServiceDocuments +
+ ", metadata='" + metadata + '\'' +
+ '}';
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1ebbbc36/lib/client-core/src/main/java/org/apache/olingo/client/core/data/ServiceDocumentItemImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/ServiceDocumentItemImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/ServiceDocumentItemImpl.java
index 3bcdaa7..fe6b59b 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/data/ServiceDocumentItemImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/data/ServiceDocumentItemImpl.java
@@ -18,13 +18,9 @@
*/
package org.apache.olingo.client.core.data;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.olingo.client.api.data.ServiceDocumentItem;
-public class ServiceDocumentItemImpl implements ServiceDocumentItem {
+public final class ServiceDocumentItemImpl implements ServiceDocumentItem {
private String name;
@@ -49,17 +45,35 @@ public class ServiceDocumentItemImpl implements ServiceDocumentItem {
}
@Override
- public boolean equals(final Object obj) {
- return EqualsBuilder.reflectionEquals(this, obj);
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ ServiceDocumentItemImpl that = (ServiceDocumentItemImpl) o;
+
+ if (name != null ? !name.equals(that.name) : that.name != null) {
+ return false;
+ }
+ return !(url != null ? !url.equals(that.url) : that.url != null);
+
}
@Override
public int hashCode() {
- return HashCodeBuilder.reflectionHashCode(this);
+ int result = name != null ? name.hashCode() : 0;
+ result = 31 * result + (url != null ? url.hashCode() : 0);
+ return result;
}
@Override
public String toString() {
- return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return "ServiceDocumentItemImpl{" +
+ "name='" + name + '\'' +
+ ", url='" + url + '\'' +
+ '}';
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1ebbbc36/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPropertyImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPropertyImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPropertyImpl.java
index ac1ad1d..eed965f 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPropertyImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPropertyImpl.java
@@ -18,11 +18,6 @@
*/
package org.apache.olingo.client.core.domain;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.olingo.client.api.domain.ClientAnnotatable;
import org.apache.olingo.client.api.domain.ClientAnnotation;
import org.apache.olingo.client.api.domain.ClientCollectionValue;
@@ -33,7 +28,10 @@ import org.apache.olingo.client.api.domain.ClientProperty;
import org.apache.olingo.client.api.domain.ClientValuable;
import org.apache.olingo.client.api.domain.ClientValue;
-public class ClientPropertyImpl implements ClientProperty, ClientAnnotatable, ClientValuable {
+import java.util.ArrayList;
+import java.util.List;
+
+public final class ClientPropertyImpl implements ClientProperty, ClientAnnotatable, ClientValuable {
private final List<ClientAnnotation> annotations = new ArrayList<ClientAnnotation>();
@@ -118,13 +116,36 @@ public class ClientPropertyImpl implements ClientProperty, ClientAnnotatable, Cl
}
@Override
- public boolean equals(final Object obj) {
- return EqualsBuilder.reflectionEquals(this, obj);
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ ClientPropertyImpl that = (ClientPropertyImpl) o;
+
+ if (annotations != null ? !annotations.equals(that.annotations) : that.annotations != null) {
+ return false;
+ }
+ if (name != null ? !name.equals(that.name) : that.name != null) {
+ return false;
+ }
+ if (value != null ? !value.equals(that.value) : that.value != null) {
+ return false;
+ }
+ return !(valuable != null ? !valuable.equals(that.valuable) : that.valuable != null);
+
}
@Override
public int hashCode() {
- return HashCodeBuilder.reflectionHashCode(this);
+ int result = annotations != null ? annotations.hashCode() : 0;
+ result = 31 * result + (name != null ? name.hashCode() : 0);
+ result = 31 * result + (value != null ? value.hashCode() : 0);
+ result = 31 * result + (valuable != null ? valuable.hashCode() : 0);
+ return result;
}
@Override
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1ebbbc36/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientValuableImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientValuableImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientValuableImpl.java
index ecae20d..4a032ce 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientValuableImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientValuableImpl.java
@@ -18,10 +18,6 @@
*/
package org.apache.olingo.client.core.domain;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.olingo.client.api.domain.ClientCollectionValue;
import org.apache.olingo.client.api.domain.ClientComplexValue;
import org.apache.olingo.client.api.domain.ClientEnumValue;
@@ -29,7 +25,7 @@ import org.apache.olingo.client.api.domain.ClientPrimitiveValue;
import org.apache.olingo.client.api.domain.ClientValuable;
import org.apache.olingo.client.api.domain.ClientValue;
-public class ClientValuableImpl implements ClientValuable {
+public final class ClientValuableImpl implements ClientValuable {
private final ClientValue value;
@@ -94,18 +90,29 @@ public class ClientValuableImpl implements ClientValuable {
}
@Override
- public boolean equals(final Object obj) {
- return EqualsBuilder.reflectionEquals(this, obj);
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ ClientValuableImpl that = (ClientValuableImpl) o;
+
+ return !(value != null ? !value.equals(that.value) : that.value != null);
+
}
@Override
public int hashCode() {
- return HashCodeBuilder.reflectionHashCode(this);
+ return value != null ? value.hashCode() : 0;
}
@Override
public String toString() {
- return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE);
+ return "ClientValuableImpl{" +
+ "value=" + value +
+ '}';
}
-
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1ebbbc36/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/FullQualifiedName.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/FullQualifiedName.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/FullQualifiedName.java
index 7b99059..4852294 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/FullQualifiedName.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/FullQualifiedName.java
@@ -20,13 +20,10 @@ package org.apache.olingo.commons.api.edm;
import java.io.Serializable;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-
/**
* A full qualified name of any element in the EDM consists of a name and a namespace.
*/
-public class FullQualifiedName implements Serializable {
+public final class FullQualifiedName implements Serializable {
private static final long serialVersionUID = -4063629050858999076L;
@@ -83,13 +80,32 @@ public class FullQualifiedName implements Serializable {
}
@Override
- public int hashCode() {
- return HashCodeBuilder.reflectionHashCode(this);
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ FullQualifiedName that = (FullQualifiedName) o;
+
+ if (namespace != null ? !namespace.equals(that.namespace) : that.namespace != null) {
+ return false;
+ }
+ if (name != null ? !name.equals(that.name) : that.name != null) {
+ return false;
+ }
+ return !(fqn != null ? !fqn.equals(that.fqn) : that.fqn != null);
+
}
@Override
- public boolean equals(final Object obj) {
- return EqualsBuilder.reflectionEquals(this, obj);
+ public int hashCode() {
+ int result = namespace != null ? namespace.hashCode() : 0;
+ result = 31 * result + (name != null ? name.hashCode() : 0);
+ result = 31 * result + (fqn != null ? fqn.hashCode() : 0);
+ return result;
}
@Override
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1ebbbc36/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/geo/SRID.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/geo/SRID.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/geo/SRID.java
index c22f59a..112dd2f 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/geo/SRID.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/edm/geo/SRID.java
@@ -18,12 +18,10 @@
*/
package org.apache.olingo.commons.api.edm.geo;
-import java.io.Serializable;
-
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.olingo.commons.api.edm.geo.Geospatial.Dimension;
+import java.io.Serializable;
+
/**
* A geometry or geography property MAY define a value for the SRID attribute. The value of this attribute identifies
* which spatial reference system is applied to values of the property on type instances.
@@ -34,7 +32,7 @@ import org.apache.olingo.commons.api.edm.geo.Geospatial.Dimension;
* Standards Track Work Product Copyright © OASIS Open 2013. All Rights Reserved. 19 November 2013 Page 22 of 83The
* valid values of the SRID attribute and their meanings are as defined by the European Petroleum Survey Group [EPSG].
*/
-public class SRID implements Serializable {
+public final class SRID implements Serializable {
private static final String VARIABLE = "variable";
@@ -75,11 +73,19 @@ public class SRID implements Serializable {
}
private String getValue() {
- return value == null
- ? dimension == Dimension.GEOMETRY
- ? "0"
- : "4326"
- : value.toString();
+ if (value == null) {
+ if (dimension == Dimension.GEOMETRY) {
+ return "0";
+ } else {
+ return "4326";
+ }
+ }
+
+ return value.toString();
+// return value == null ? dimension == Dimension.GEOMETRY
+// ? "0"
+// : "4326"
+// : value.toString();
}
private boolean isVariable() {
@@ -91,13 +97,32 @@ public class SRID implements Serializable {
}
@Override
- public int hashCode() {
- return HashCodeBuilder.reflectionHashCode(this);
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ SRID srid = (SRID) o;
+
+ if (dimension != srid.dimension) {
+ return false;
+ }
+ if (value != null ? !value.equals(srid.value) : srid.value != null) {
+ return false;
+ }
+ return !(variable != null ? !variable.equals(srid.variable) : srid.variable != null);
+
}
@Override
- public boolean equals(final Object obj) {
- return EqualsBuilder.reflectionEquals(this, obj);
+ public int hashCode() {
+ int result = dimension != null ? dimension.hashCode() : 0;
+ result = 31 * result + (value != null ? value.hashCode() : 0);
+ result = 31 * result + (variable != null ? variable.hashCode() : 0);
+ return result;
}
@Override
@@ -106,5 +131,4 @@ public class SRID implements Serializable {
? VARIABLE
: getValue();
}
-
}
[02/18] olingo-odata4 git commit: OLINGO-738: Adding upsertEntity
feature for the server-extension framework
Posted by ch...@apache.org.
OLINGO-738: Adding upsertEntity feature for the server-extension framework
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/cb0f7f2d
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/cb0f7f2d
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/cb0f7f2d
Branch: refs/heads/OLINGO-640
Commit: cb0f7f2d7012d9e0a46024e7e9fe21bc09704c42
Parents: 1ebbbc3
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Thu Jul 23 18:00:50 2015 -0500
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Thu Jul 23 18:00:50 2015 -0500
----------------------------------------------------------------------
.../apache/olingo/server/core/ServiceHandler.java | 15 +++++++++++++++
.../server/core/legacy/ProcessorServiceHandler.java | 7 +++++++
.../olingo/server/core/requests/DataRequest.java | 2 +-
.../apache/olingo/server/example/TripPinHandler.java | 12 ++++++++++++
4 files changed, 35 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/cb0f7f2d/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java
index a7753ec..a223120 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ServiceHandler.java
@@ -102,6 +102,21 @@ public interface ServiceHandler extends Processor {
EntityResponse response) throws ODataLibraryException, ODataApplicationException;
/**
+ * Update or create the entity object. If based on passed in entity object's key value, if
+ * entity exists update the entity, else create a new entity
+ * @param request
+ * @param entity - Entity to create or update
+ * @param merge - in the case of update, true to do merge operation with current entity,
+ * false the entity needs to be replaced
+ * @param entityETag - previous entity tag if provided by the user. "*" means allow.
+ * @param response
+ * @throws ODataLibraryException
+ * @throws ODataApplicationException
+ */
+ void upsertEntity(DataRequest request, Entity entity, boolean merge, String entityETag,
+ EntityResponse response) throws ODataLibraryException, ODataApplicationException;
+
+ /**
* Delete the Entity
* @param request
* @param entityETag - entity tag to match, if provided by the user. "*" means allow
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/cb0f7f2d/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java
index acbc8c0..b65f19c 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/legacy/ProcessorServiceHandler.java
@@ -430,4 +430,11 @@ public class ProcessorServiceHandler implements ServiceHandler {
throw new ODataHandlerException("not implemented",
ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
}
+
+ @Override
+ public void upsertEntity(DataRequest request, Entity entity, boolean merge, String entityETag,
+ EntityResponse response) throws ODataLibraryException, ODataApplicationException {
+ throw new ODataHandlerException("not implemented",
+ ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED);
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/cb0f7f2d/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
index 7f2273c..2966d86 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
@@ -317,7 +317,7 @@ public class DataRequest extends ServiceRequest {
getContextURL(odata), false, response, getReturnRepresentation());
handler.createEntity(DataRequest.this, getEntityFromClient(), entityResponse);
} else {
- handler.updateEntity(DataRequest.this, getEntityFromClient(), isPATCH(), getETag(),
+ handler.upsertEntity(DataRequest.this, getEntityFromClient(), isPATCH(), getETag(),
entityResponse);
}
} else if (isPOST()) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/cb0f7f2d/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
index 6ca0fcd..db06558 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinHandler.java
@@ -544,4 +544,16 @@ public class TripPinHandler implements ServiceHandler {
public void crossJoin(DataRequest dataRequest, List<String> entitySetNames, ODataResponse response) {
response.setStatusCode(200);
}
+
+ @Override
+ public void upsertEntity(DataRequest request, Entity entity, boolean merge, String entityETag,
+ EntityResponse response) throws ODataLibraryException, ODataApplicationException {
+ EdmEntitySet edmEntitySet = request.getEntitySet();
+ Entity currentEntity = this.dataModel.getEntity(edmEntitySet.getName(), request.getKeyPredicates());
+ if(currentEntity == null) {
+ createEntity(request, entity, response);
+ } else {
+ updateEntity(request, entity, merge, entityETag, response);
+ }
+ }
}
[11/18] olingo-odata4 git commit: [OLINGO-731] Added tests
Posted by ch...@apache.org.
[OLINGO-731] Added tests
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/57a11aff
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/57a11aff
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/57a11aff
Branch: refs/heads/OLINGO-640
Commit: 57a11aff6b1658e66424290423a4cadb104661f5
Parents: b146a40
Author: Christian Amend <ch...@sap.com>
Authored: Tue Jul 28 15:35:50 2015 +0200
Committer: Christian Amend <ch...@sap.com>
Committed: Tue Jul 28 15:47:23 2015 +0200
----------------------------------------------------------------------
.../apache/olingo/server/core/ODataHandler.java | 16 +-
.../core/debug/DebugResponseHelperImpl.java | 15 +-
.../olingo/server/core/debug/DebugTabBody.java | 19 ++-
.../server/core/debug/DebugTabRequest.java | 99 +++++++-----
.../server/core/debug/DebugTabResponse.java | 20 ++-
.../server/core/debug/DebugTabServer.java | 10 +-
.../server/core/debug/ServerCoreDebugger.java | 7 +-
.../serializer/BatchResponseSerializer.java | 1 -
.../server/core/debug/AbstractDebugTabTest.java | 58 +++++++
.../server/core/debug/DebugTabBodyTest.java | 37 +++++
.../server/core/debug/DebugTabRequestTest.java | 155 +++++++++++++++++++
.../server/core/debug/DebugTabResponseTest.java | 79 ++++++++++
.../server/core/debug/DebugTabServerTest.java | 84 ++++++++++
.../core/debug/ServerCoreDebuggerTest.java | 121 +++++++++++++++
14 files changed, 651 insertions(+), 70 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/57a11aff/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
index 1d1b270..bfbc5ac 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
@@ -74,10 +74,9 @@ public class ODataHandler {
public ODataResponse process(final ODataRequest request) {
ODataResponse response = new ODataResponse();
+ int measurementHandel = debugger.startRuntimeMeasurement("ODataHandler", "processInternal");
try {
-
processInternal(request, response);
-
} catch (final UriValidationException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
handleException(request, response, serverError, e);
@@ -112,6 +111,7 @@ public class ODataHandler {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e);
handleException(request, response, serverError, e);
}
+ debugger.stopRuntimeMeasurement(measurementHandel);
return response;
}
@@ -119,13 +119,19 @@ public class ODataHandler {
throws ODataApplicationException, ODataLibraryException {
validateODataVersion(request, response);
+ int measurementUriParser = debugger.startRuntimeMeasurement("UriParser", "parseUri");
uriInfo = new Parser().parseUri(request.getRawODataPath(), request.getRawQueryPath(), null,
serviceMetadata.getEdm());
+ debugger.stopRuntimeMeasurement(measurementUriParser);
+ int measurementUriValidator = debugger.startRuntimeMeasurement("UriValidator", "validate");
final HttpMethod method = request.getMethod();
new UriValidator().validate(uriInfo, method);
+ debugger.stopRuntimeMeasurement(measurementUriValidator);
+ int measurementDispatcher = debugger.startRuntimeMeasurement("Dispatcher", "dispatch");
new ODataDispatcher(method, uriInfo, this).dispatch(request, response);
+ debugger.stopRuntimeMeasurement(measurementDispatcher);
}
public void handleException(final ODataRequest request, final ODataResponse response,
@@ -146,7 +152,9 @@ public class ODataHandler {
} catch (final ContentNegotiatorException e) {
requestedContentType = ContentType.JSON;
}
+ int measurementHandle = debugger.startRuntimeMeasurement("ErrorProcessor", "processError");
exceptionProcessor.processError(request, response, serverError, requestedContentType);
+ debugger.stopRuntimeMeasurement(measurementHandle);
}
private void validateODataVersion(final ODataRequest request, final ODataResponse response)
@@ -196,8 +204,8 @@ public class ODataHandler {
public Exception getLastThrownException() {
return lastThrownException;
}
-
- public UriInfo getUriInfo(){
+
+ public UriInfo getUriInfo() {
return uriInfo;
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/57a11aff/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java
index d99dd4c..94ab544 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java
@@ -76,7 +76,7 @@ public class DebugResponseHelperImpl implements DebugResponseHelper {
+ new Date().toString().replace(' ', '_').replace(':', '.') + ".html");
// Download is the same as html except for the above header
case HTML:
- String title = debugInfo.getRequest() == null ?
+ String title = debugInfo.getRequest() == null ?
"V4 Service" : "V4 Service: " + debugInfo.getRequest().getRawODataPath();
body = wrapInHtml(parts, title);
contentTypeString = ContentType.TEXT_HTML.toContentTypeString();
@@ -164,7 +164,7 @@ public class DebugResponseHelperImpl implements DebugResponseHelper {
gen.writeEndObject();
gen.close();
- csb.close();
+ csb.closeWrite();
return csb.getInputStream();
}
@@ -258,14 +258,15 @@ public class DebugResponseHelperImpl implements DebugResponseHelper {
.append("</thead>\n<tbody>\n");
for (final String name : entries.keySet()) {
final String value = entries.get(name);
+ writer.append("<tr><td class=\"name\">").append(name).append("</td>")
+ .append("<td class=\"value\">");
if (value != null) {
- writer.append("<tr><td class=\"name\">").append(name).append("</td>")
- .append("<td class=\"value\">")
- .append(escapeHtml(value))
- .append("</td></tr>\n");
+ writer.append(escapeHtml(value));
+ }else{
+ writer.append("null");
}
+ writer.append("</td></tr>\n");
}
writer.append("</tbody>\n</table>\n");
}
-
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/57a11aff/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabBody.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabBody.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabBody.java
index 43e9ba6..5608d58 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabBody.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabBody.java
@@ -50,11 +50,15 @@ public class DebugTabBody implements DebugTab {
public DebugTabBody(final ODataResponse response, final String serviceRoot) {
this.response = response;
- this.serviceRoot = serviceRoot;
- final String contentType = response.getHeaders().get(HttpHeader.CONTENT_TYPE);
- // TODO: Differentiate better
- if (contentType != null) {
- responseContent = ResponseContent.JSON;
+ this.serviceRoot = serviceRoot == null ? "/" : serviceRoot;
+ if (response != null) {
+ final String contentType = response.getHeaders().get(HttpHeader.CONTENT_TYPE);
+ // TODO: Differentiate better
+ if (contentType != null) {
+ responseContent = ResponseContent.JSON;
+ } else {
+ responseContent = ResponseContent.TEXT;
+ }
} else {
responseContent = ResponseContent.TEXT;
}
@@ -74,7 +78,7 @@ public class DebugTabBody implements DebugTab {
//
@Override
public void appendJson(final JsonGenerator gen) throws IOException {
- if (response.getContent() == null) {
+ if (response == null || response.getContent() == null) {
gen.writeNull();
} else {
gen.writeString(getContentString());
@@ -106,7 +110,8 @@ public class DebugTabBody implements DebugTab {
@Override
public void appendHtml(final Writer writer) throws IOException {
- final String body = response.getContent() == null ? "ODataLibrary: null body." : getContentString();
+ final String body =
+ response == null || response.getContent() == null ? "ODataLibrary: No body." : getContentString();
switch (responseContent) {
case XML:
writer.append("<pre class=\"code").append("xml").append("\">\n");
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/57a11aff/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabRequest.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabRequest.java
index 8eba537..be38f68 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabRequest.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabRequest.java
@@ -20,7 +20,7 @@ package org.apache.olingo.server.core.debug;
import java.io.IOException;
import java.io.Writer;
-import java.util.LinkedHashMap;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -36,33 +36,20 @@ public class DebugTabRequest implements DebugTab {
private final String method;
private final String uri;
private final String protocol;
- private final Map<String, String> headers;
+ private final Map<String, List<String>> headers;
public DebugTabRequest(ODataRequest request) {
- method = request.getMethod() == null ? "unkown" : request.getMethod().toString();
- uri = request.getRawRequestUri() == null ? "unkown" : request.getRawRequestUri();
- protocol = request.getProtocol() == null ? "unkown" : request.getProtocol();
- // TODO: Should we really wrap the headers here or keep the original structure?
- headers = wrapHeaders(request.getAllHeaders());
- }
-
- private Map<String, String> wrapHeaders(Map<String, List<String>> allHeaders) {
- Map<String, String> localHeaders = new LinkedHashMap<String, String>();
- for (Map.Entry<String, List<String>> entry : allHeaders.entrySet()) {
- String value = null;
- if (entry.getValue() != null) {
- value = "";
- boolean first = true;
- for (String valuePart : entry.getValue()) {
- if (!first) {
- value = value + ", ";
- }
- value = value + valuePart;
- }
- }
- localHeaders.put(entry.getKey(), value);
+ if (request != null) {
+ method = request.getMethod() == null ? "unkown" : request.getMethod().toString();
+ uri = request.getRawRequestUri() == null ? "unkown" : request.getRawRequestUri();
+ protocol = request.getProtocol() == null ? "unkown" : request.getProtocol();
+ headers = request.getAllHeaders();
+ } else {
+ method = "unkown";
+ uri = "unkown";
+ protocol = "unkown";
+ headers = Collections.emptyMap();
}
- return localHeaders;
}
@Override
@@ -70,25 +57,26 @@ public class DebugTabRequest implements DebugTab {
writer.append("<h2>Request Method</h2>\n")
.append("<p>").append(method).append("</p>\n")
.append("<h2>Request URI</h2>\n")
- .append("<p>").append(DebugResponseHelperImpl.escapeHtml(uri.toString())).append("</p>\n")
+ .append("<p>").append(DebugResponseHelperImpl.escapeHtml(uri)).append("</p>\n")
.append("<h2>Request Protocol</h2>\n")
- .append("<p>").append(protocol).append("</p>\n");
+ .append("<p>").append(DebugResponseHelperImpl.escapeHtml(protocol)).append("</p>\n");
writer.append("<h2>Request Headers</h2>\n");
- DebugResponseHelperImpl.appendHtmlTable(writer, headers);
-
-// .append("<table>\n<thead>\n")
-// .append("<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n")
-// .append("</thead>\n<tbody>\n");
-// for (final String name : headers.keySet()) {
-// for (final String value : headers.get(name)) {
-// if (value != null) {
-// writer.append("<tr><td class=\"name\">").append(name).append("</td>")
-// .append("<td class=\"value\">").append(DebugResponseHelperImpl.escapeHtml(value))
-// .append("</td></tr>\n");
-// }
-// }
-// }
-// writer.append("</tbody>\n</table>\n");
+
+ writer.append("<table>\n<thead>\n")
+ .append("<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n")
+ .append("</thead>\n<tbody>\n");
+ for (final Map.Entry<String, List<String>> entry : headers.entrySet()) {
+ List<String> headersList = entry.getValue();
+ if (headersList != null && !headersList.isEmpty()) {
+ for (String headerValue : headersList) {
+ writer.append("<tr><td class=\"name\">").append(entry.getKey()).append("</td>")
+ .append("<td class=\"value\">")
+ .append(DebugResponseHelperImpl.escapeHtml(headerValue))
+ .append("</td></tr>\n");
+ }
+ }
+ }
+ writer.append("</tbody>\n</table>\n");
}
@Override
@@ -107,7 +95,32 @@ public class DebugTabRequest implements DebugTab {
if (!headers.isEmpty()) {
gen.writeFieldName("headers");
- DebugResponseHelperImpl.appendJsonTable(gen, headers);
+
+ gen.writeStartObject();
+
+ for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
+ List<String> headersList = entry.getValue();
+ if (headersList != null && !headersList.isEmpty()) {
+ if (headersList.size() == 1) {
+ gen.writeStringField(entry.getKey(), headersList.get(0));
+ } else {
+ gen.writeFieldName(entry.getKey());
+ gen.writeStartArray();
+ for (String headerValue : headersList) {
+ if (headerValue != null) {
+ gen.writeString(headerValue);
+ } else {
+ gen.writeNull();
+ }
+ }
+ gen.writeEndArray();
+ }
+ } else {
+ gen.writeNullField(entry.getKey());
+ }
+ }
+
+ gen.writeEndObject();
}
gen.writeEndObject();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/57a11aff/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabResponse.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabResponse.java
index 5cb153c..528cf61 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabResponse.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabResponse.java
@@ -20,6 +20,7 @@ package org.apache.olingo.server.core.debug;
import java.io.IOException;
import java.io.Writer;
+import java.util.Collections;
import java.util.Map;
import org.apache.olingo.commons.api.http.HttpStatusCode;
@@ -39,9 +40,14 @@ public class DebugTabResponse implements DebugTab {
public DebugTabResponse(final ODataResponse applicationResponse, final String serviceRoot) {
this.response = applicationResponse;
- this.serviceRoot = serviceRoot;
- status = HttpStatusCode.fromStatusCode(response.getStatusCode());
- headers = response.getHeaders();
+ if (response != null) {
+ status = HttpStatusCode.fromStatusCode(response.getStatusCode());
+ headers = response.getHeaders();
+ } else {
+ status = HttpStatusCode.INTERNAL_SERVER_ERROR;
+ headers = Collections.emptyMap();
+ }
+ this.serviceRoot = serviceRoot == null ? "/" : serviceRoot;
}
@Override
@@ -67,7 +73,11 @@ public class DebugTabResponse implements DebugTab {
}
gen.writeFieldName("body");
- new DebugTabBody(response, serviceRoot).appendJson(gen);
+ if (response != null && response.getContent() != null) {
+ new DebugTabBody(response, serviceRoot).appendJson(gen);
+ } else {
+ gen.writeNull();
+ }
gen.writeEndObject();
}
@@ -80,7 +90,7 @@ public class DebugTabResponse implements DebugTab {
.append("<h2>Response Headers</h2>\n");
DebugResponseHelperImpl.appendHtmlTable(writer, headers);
writer.append("<h2>Response Body</h2>\n");
- if (response.getContent() != null) {
+ if (response != null && response.getContent() != null) {
new DebugTabBody(response, serviceRoot).appendHtml(writer);
} else {
writer.append("<p>ODataLibrary: no response body</p>");
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/57a11aff/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabServer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabServer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabServer.java
index 4eb95ba..2faae3e 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabServer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabServer.java
@@ -42,7 +42,11 @@ public class DebugTabServer implements DebugTab {
@Override
public void appendJson(JsonGenerator gen) throws IOException {
- DebugResponseHelperImpl.appendJsonTable(gen, serverEnvironmentVaribles);
+ if (serverEnvironmentVaribles != null && !serverEnvironmentVaribles.isEmpty()) {
+ DebugResponseHelperImpl.appendJsonTable(gen, serverEnvironmentVaribles);
+ } else {
+ gen.writeNull();
+ }
}
@Override
@@ -52,6 +56,8 @@ public class DebugTabServer implements DebugTab {
.append("<p>").append(pack.getImplementationTitle())
.append(" Version ").append(pack.getImplementationVersion()).append("</p>\n")
.append("<h2>Server Environment</h2>\n");
- DebugResponseHelperImpl.appendHtmlTable(writer, serverEnvironmentVaribles);
+ if (serverEnvironmentVaribles != null && !serverEnvironmentVaribles.isEmpty()) {
+ DebugResponseHelperImpl.appendHtmlTable(writer, serverEnvironmentVaribles);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/57a11aff/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/ServerCoreDebugger.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/ServerCoreDebugger.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/ServerCoreDebugger.java
index fcf611d..8bdbe39 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/ServerCoreDebugger.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/ServerCoreDebugger.java
@@ -64,6 +64,11 @@ public class ServerCoreDebugger {
public ODataResponse createDebugResponse(final HttpServletRequest request, final Exception exception,
final ODataRequest odRequest, final ODataResponse odResponse, UriInfo uriInfo,
Map<String, String> serverEnvironmentVaribles) {
+ //Failsafe so we do not generate unauthorized debug messages
+ if(!isDebugMode){
+ return odResponse;
+ }
+
try {
DebugInformation debugInfo =
createDebugInformation(request, exception, odRequest, odResponse, uriInfo, serverEnvironmentVaribles);
@@ -80,7 +85,7 @@ public class ServerCoreDebugger {
odResponse.setHeader(HttpHeader.CONTENT_TYPE, ContentType.TEXT_PLAIN.toContentTypeString());
InputStream content = new ByteArrayInputStream("ODataLibrary: Could not assemble debug response.".getBytes());
odResponse.setContent(content);
- return null;
+ return odResponse;
}
private DebugInformation createDebugInformation(final HttpServletRequest request, final Exception exception,
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/57a11aff/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
index 377c5e1..c907b8f 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/BatchResponseSerializer.java
@@ -22,7 +22,6 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/57a11aff/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/AbstractDebugTabTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/AbstractDebugTabTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/AbstractDebugTabTest.java
new file mode 100644
index 0000000..43b1aaa
--- /dev/null
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/AbstractDebugTabTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
+
+import com.fasterxml.jackson.core.JsonEncoding;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
+
+public abstract class AbstractDebugTabTest {
+
+ protected String createHtml(DebugTab tab) throws Exception {
+ StringWriter writer = new StringWriter();
+ tab.appendHtml(writer);
+ writer.flush();
+ byte[] bytes = writer.toString().getBytes("UTF-8");
+ return IOUtils.toString(new ByteArrayInputStream(bytes));
+ }
+
+ protected String createJson(DebugTab requestTab) throws IOException {
+ CircleStreamBuffer csb = new CircleStreamBuffer();
+ JsonGenerator gen = new JsonFactory().createGenerator(csb.getOutputStream(), JsonEncoding.UTF8);
+ requestTab.appendJson(gen);
+ gen.flush();
+ gen.close();
+ csb.closeWrite();
+ return IOUtils.toString(csb.getInputStream());
+ }
+
+ protected void print(DebugTab tab) throws Exception{
+ System.out.println(createJson(tab));
+ System.out.println("---------------------------------------------------------");
+ System.out.println(createHtml(tab));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/57a11aff/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabBodyTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabBodyTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabBodyTest.java
new file mode 100644
index 0000000..7d3a58e
--- /dev/null
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabBodyTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.server.core.debug;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class DebugTabBodyTest extends AbstractDebugTabTest {
+
+ @Test
+ public void nullResponseMustNotLeadToException() throws Exception {
+ DebugTabBody tab = new DebugTabBody(null, null);
+
+ String expectedHtml = "<pre class=\"code\">\n"
+ + "ODataLibrary: No body.</pre>\n";
+
+ assertEquals("null", createJson(tab));
+ assertEquals(expectedHtml, createHtml(tab));
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/57a11aff/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabRequestTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabRequestTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabRequestTest.java
new file mode 100644
index 0000000..3689301
--- /dev/null
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabRequestTest.java
@@ -0,0 +1,155 @@
+/*
+ * 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.server.core.debug;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.olingo.commons.api.http.HttpMethod;
+import org.apache.olingo.server.api.ODataRequest;
+import org.junit.Test;
+
+public class DebugTabRequestTest extends AbstractDebugTabTest {
+
+ @Test
+ public void initialRequestMustNotleadToException() throws Exception {
+ String expectedJson = "{\"method\":\"unkown\",\"uri\":\"unkown\",\"protocol\":\"unkown\"}";
+ String expectedHtml = "<h2>Request Method</h2>\n"
+ + "<p>unkown</p>\n"
+ + "<h2>Request URI</h2>\n"
+ + "<p>unkown</p>\n"
+ + "<h2>Request Protocol</h2>\n"
+ + "<p>unkown</p>\n"
+ + "<h2>Request Headers</h2>\n"
+ + "<table>\n"
+ + "<thead>\n"
+ + "<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n"
+ + "</thead>\n"
+ + "<tbody>\n"
+ + "</tbody>\n"
+ + "</table>\n";
+
+ DebugTabRequest requestTab = new DebugTabRequest(null);
+ assertEquals(expectedJson, createJson(requestTab));
+ assertEquals(expectedHtml, createHtml(requestTab));
+
+ requestTab = new DebugTabRequest(new ODataRequest());
+ assertEquals(expectedJson, createJson(requestTab));
+ assertEquals(expectedHtml, createHtml(requestTab));
+ }
+
+ @Test
+ public void onlyProtocolNotSet() throws Exception {
+ String expectedJson = "{\"method\":\"GET\",\"uri\":\"def&\",\"protocol\":\"unkown\"}";
+ String expectedHtml = "<h2>Request Method</h2>\n"
+ + "<p>GET</p>\n"
+ + "<h2>Request URI</h2>\n"
+ + "<p>def&</p>\n"
+ + "<h2>Request Protocol</h2>\n"
+ + "<p>unkown</p>\n"
+ + "<h2>Request Headers</h2>\n"
+ + "<table>\n"
+ + "<thead>\n"
+ + "<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n"
+ + "</thead>\n"
+ + "<tbody>\n"
+ + "</tbody>\n"
+ + "</table>\n";
+
+ ODataRequest oDataRequest = new ODataRequest();
+ oDataRequest.setMethod(HttpMethod.GET);
+ oDataRequest.setRawRequestUri("def&");
+
+ DebugTabRequest requestTab = new DebugTabRequest(oDataRequest);
+ assertEquals(expectedJson, createJson(requestTab));
+ assertEquals(expectedHtml, createHtml(requestTab));
+ }
+
+ @Test
+ public void singleHeaderValue() throws Exception {
+ String expectedJson =
+ "{\"method\":\"GET\",\"uri\":\"def&\",\"protocol\":\"def&\",\"headers\":{\"HEADERNAME\":\"Value1\"}}";
+ String expectedHtml = "<h2>Request Method</h2>\n"
+ + "<p>GET</p>\n"
+ + "<h2>Request URI</h2>\n"
+ + "<p>def&</p>\n"
+ + "<h2>Request Protocol</h2>\n"
+ + "<p>def&</p>\n"
+ + "<h2>Request Headers</h2>\n"
+ + "<table>\n"
+ + "<thead>\n"
+ + "<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n"
+ + "</thead>\n"
+ + "<tbody>\n"
+ + "<tr><td class=\"name\">HEADERNAME</td><td class=\"value\">Value1</td></tr>\n"
+ + "</tbody>\n"
+ + "</table>\n";
+
+ ODataRequest oDataRequest = new ODataRequest();
+ oDataRequest.setMethod(HttpMethod.GET);
+ oDataRequest.setRawRequestUri("def&");
+ oDataRequest.setProtocol("def&");
+ List<String> headerValues = new ArrayList<String>();
+ headerValues.add("Value1");
+ oDataRequest.addHeader("HeaderName", headerValues);
+
+ DebugTabRequest requestTab = new DebugTabRequest(oDataRequest);
+ System.out.println(createHtml(requestTab));
+ assertEquals(expectedJson, createJson(requestTab));
+ assertEquals(expectedHtml, createHtml(requestTab));
+ }
+
+ @Test
+ public void multiHeaderValueResultsInMap() throws Exception {
+ String expectedJson = "{\"method\":\"GET\",\"uri\":\"def&\",\"protocol\":\"def&\","
+ + "\"headers\":{\"HEADERNAME\":[\"Value1\",\"Value2\"]}}";
+ String expectedHtml = "<h2>Request Method</h2>\n"
+ + "<p>GET</p>\n"
+ + "<h2>Request URI</h2>\n"
+ + "<p>def&</p>\n"
+ + "<h2>Request Protocol</h2>\n"
+ + "<p>def&</p>\n"
+ + "<h2>Request Headers</h2>\n"
+ + "<table>\n"
+ + "<thead>\n"
+ + "<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n"
+ + "</thead>\n"
+ + "<tbody>\n"
+ + "<tr><td class=\"name\">HEADERNAME</td><td class=\"value\">Value1</td></tr>\n"
+ + "<tr><td class=\"name\">HEADERNAME</td><td class=\"value\">Value2</td></tr>\n"
+ + "</tbody>\n"
+ + "</table>\n";
+
+ ODataRequest oDataRequest = new ODataRequest();
+ oDataRequest.setMethod(HttpMethod.GET);
+ oDataRequest.setRawRequestUri("def&");
+ oDataRequest.setProtocol("def&");
+ List<String> headerValues = new ArrayList<String>();
+ headerValues.add("Value1");
+ headerValues.add("Value2");
+ oDataRequest.addHeader("HeaderName", headerValues);
+
+ DebugTabRequest requestTab = new DebugTabRequest(oDataRequest);
+ assertEquals(expectedJson, createJson(requestTab));
+ assertEquals(expectedHtml, createHtml(requestTab));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/57a11aff/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabResponseTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabResponseTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabResponseTest.java
new file mode 100644
index 0000000..af55a40
--- /dev/null
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabResponseTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.server.core.debug;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.ODataResponse;
+import org.junit.Test;
+
+public class DebugTabResponseTest extends AbstractDebugTabTest {
+
+ @Test
+ public void nullResponseMustNotLeadToException() throws Exception {
+ DebugTabResponse tab = new DebugTabResponse(null, null);
+
+ String expectedJson = "{\"status\":{\"code\":\"500\",\"info\":\"Internal Server Error\"},\"body\":null}";
+ String expectedHtml = "<h2>Status Code</h2>\n"
+ + "<p>500 Internal Server Error</p>\n"
+ + "<h2>Response Headers</h2>\n"
+ + "<table>\n"
+ + "<thead>\n"
+ + "<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n"
+ + "</thead>\n"
+ + "<tbody>\n"
+ + "</tbody>\n"
+ + "</table>\n"
+ + "<h2>Response Body</h2>\n"
+ + "<p>ODataLibrary: no response body</p>";
+
+ assertEquals(expectedJson, createJson(tab));
+ assertEquals(expectedHtml, createHtml(tab));
+ }
+
+ @Test
+ public void withInformationNoBody() throws Exception {
+ ODataResponse response = new ODataResponse();
+ response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+ response.setHeader("headername", "headervalue");
+ response.setHeader("headername2", "headervalue2");
+ DebugTabResponse tab = new DebugTabResponse(response, null);
+
+ String expectedJson = "{\"status\":{\"code\":\"204\",\"info\":\"No Content\"},"
+ + "\"headers\":{\"headername\":\"headervalue\",\"headername2\":\"headervalue2\"},\"body\":null}";
+ String expectedHtml = "<h2>Status Code</h2>\n"
+ + "<p>204 No Content</p>\n"
+ + "<h2>Response Headers</h2>\n"
+ + "<table>\n"
+ + "<thead>\n"
+ + "<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n"
+ + "</thead>\n"
+ + "<tbody>\n"
+ + "<tr><td class=\"name\">headername</td><td class=\"value\">headervalue</td></tr>\n"
+ + "<tr><td class=\"name\">headername2</td><td class=\"value\">headervalue2</td></tr>\n"
+ + "</tbody>\n"
+ + "</table>\n"
+ + "<h2>Response Body</h2>\n"
+ + "<p>ODataLibrary: no response body</p>";
+ assertEquals(expectedJson, createJson(tab));
+ assertEquals(expectedHtml, createHtml(tab));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/57a11aff/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabServerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabServerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabServerTest.java
new file mode 100644
index 0000000..dc4748d
--- /dev/null
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/DebugTabServerTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.server.core.debug;
+
+import static org.junit.Assert.*;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.junit.Test;
+
+public class DebugTabServerTest extends AbstractDebugTabTest {
+
+ @Test
+ public void nullServerInformationMustNotleadToException() throws Exception {
+ DebugTabServer serverTab = new DebugTabServer(null);
+
+ assertEquals("null", createJson(serverTab));
+ String html = createHtml(serverTab);
+ assertTrue(html.startsWith("<h2>Library Version</h2>"));
+ assertTrue(html.endsWith("<h2>Server Environment</h2>\n"));
+ }
+
+ @Test
+ public void initialServerInformationMustNotleadToException() throws Exception {
+ Map<String, String> env = Collections.emptyMap();
+ DebugTabServer serverTab = new DebugTabServer(env);
+
+ assertEquals("null", createJson(serverTab));
+ String html = createHtml(serverTab);
+ assertTrue(html.startsWith("<h2>Library Version</h2>"));
+ assertTrue(html.endsWith("<h2>Server Environment</h2>\n"));
+ }
+
+ @Test
+ public void twoParametersNoNull() throws Exception {
+ Map<String, String> env = new LinkedHashMap<String, String>();
+ env.put("key1", "value1");
+ env.put("key2", "value2");
+ DebugTabServer serverTab = new DebugTabServer(env);
+
+ String expectedJson = "{\"key1\":\"value1\",\"key2\":\"value2\"}";
+
+ assertEquals(expectedJson, createJson(serverTab));
+ String html = createHtml(serverTab);
+ assertTrue(html.contains("<tr><td class=\"name\">key1</td><td class=\"value\">value1</td></tr>"));
+ assertTrue(html.contains("<tr><td class=\"name\">key2</td><td class=\"value\">value2</td></tr>"));
+ assertTrue(html.endsWith("</table>\n"));
+ }
+
+ @Test
+ public void twoParametersWithNull() throws Exception {
+ Map<String, String> env = new LinkedHashMap<String, String>();
+ env.put("key1", null);
+ env.put("key2", null);
+ DebugTabServer serverTab = new DebugTabServer(env);
+
+ String expectedJson = "{\"key1\":null,\"key2\":null}";
+
+ assertEquals(expectedJson, createJson(serverTab));
+ String html = createHtml(serverTab);
+ assertTrue(html.contains("<tr><td class=\"name\">key1</td><td class=\"value\">null</td></tr>"));
+ assertTrue(html.contains("<tr><td class=\"name\">key2</td><td class=\"value\">null</td></tr>"));
+ assertTrue(html.endsWith("</table>\n"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/57a11aff/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/ServerCoreDebuggerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/ServerCoreDebuggerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/ServerCoreDebuggerTest.java
new file mode 100644
index 0000000..32ec195
--- /dev/null
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/debug/ServerCoreDebuggerTest.java
@@ -0,0 +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.server.core.debug;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.commons.api.ODataRuntimeException;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.debug.DebugInformation;
+import org.apache.olingo.server.api.debug.DebugSupport;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ServerCoreDebuggerTest {
+
+ private ServerCoreDebugger debugger;
+
+ @Before
+ public void setupDebugger() {
+ debugger = new ServerCoreDebugger(OData.newInstance());
+ debugger.setDebugSupportProcessor(new LocalDebugProcessor());
+ }
+
+ @Test
+ public void standardIsDebugModeIsFlase() {
+ assertFalse(debugger.isDebugMode());
+ }
+
+ @Test
+ public void resolveDebugModeNoDebugSupportProcessor() {
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ when(request.getParameter(DebugSupport.ODATA_DEBUG_QUERY_PARAMETER)).thenReturn(DebugSupport.ODATA_DEBUG_JSON);
+
+ ServerCoreDebugger localDebugger = new ServerCoreDebugger(OData.newInstance());
+ localDebugger.resolveDebugMode(request);
+ assertFalse(debugger.isDebugMode());
+ }
+
+ @Test
+ public void resolveDebugModeNullParameter() {
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ when(request.getParameter(DebugSupport.ODATA_DEBUG_QUERY_PARAMETER)).thenReturn(null);
+ debugger.resolveDebugMode(request);
+ assertFalse(debugger.isDebugMode());
+ }
+
+ @Test
+ public void resolveDebugModeJsonNotAuthorized() {
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ when(request.getParameter(DebugSupport.ODATA_DEBUG_QUERY_PARAMETER)).thenReturn(DebugSupport.ODATA_DEBUG_JSON);
+
+ DebugSupport debugSupportMock = mock(DebugSupport.class);
+ when(debugSupportMock.isUserAuthorized()).thenReturn(false);
+
+ ServerCoreDebugger localDebugger = new ServerCoreDebugger(OData.newInstance());
+ localDebugger.setDebugSupportProcessor(debugSupportMock);
+
+ localDebugger.resolveDebugMode(request);
+ assertFalse(debugger.isDebugMode());
+ }
+
+ @Test
+ public void testFailResponse() throws IOException {
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ when(request.getParameter(DebugSupport.ODATA_DEBUG_QUERY_PARAMETER)).thenReturn(DebugSupport.ODATA_DEBUG_JSON);
+ debugger.resolveDebugMode(request);
+ ODataResponse debugResponse = debugger.createDebugResponse(null, null, null, null, null, null);
+ assertEquals(500, debugResponse.getStatusCode());
+ assertEquals("ODataLibrary: Could not assemble debug response.", IOUtils.toString(debugResponse.getContent()));
+ }
+
+ @Test
+ public void noDebugModeCreateDebugResponseCallMustDoNothing() {
+ ODataResponse odResponse = new ODataResponse();
+ ODataResponse debugResponse = debugger.createDebugResponse(null, null, null, odResponse, null, null);
+
+ assertTrue(odResponse == debugResponse);
+ }
+
+ public class LocalDebugProcessor implements DebugSupport {
+
+ @Override
+ public void init(OData odata) {}
+
+ @Override
+ public boolean isUserAuthorized() {
+ return true;
+ }
+
+ @Override
+ public ODataResponse createDebugResponse(String debugFormat, DebugInformation debugInfo) {
+ throw new ODataRuntimeException("Test");
+ }
+ }
+}
[04/18] olingo-odata4 git commit: [OLINGO-731] Debug interfaces part 2
Posted by ch...@apache.org.
[OLINGO-731] Debug interfaces part 2
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/fb65199d
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/fb65199d
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/fb65199d
Branch: refs/heads/OLINGO-640
Commit: fb65199d288892d281678d068ce37c44da54be04
Parents: 8f763aa
Author: Christian Amend <ch...@sap.com>
Authored: Fri Jul 10 10:50:33 2015 +0200
Committer: Christian Amend <ch...@sap.com>
Committed: Fri Jul 24 09:29:13 2015 +0200
----------------------------------------------------------------------
.../apache/olingo/server/api/ODataRequest.java | 22 +-
.../server/api/debug/DebugResponseHelper.java | 9 +-
.../olingo/server/api/debug/DebugSupport.java | 5 +-
.../server/api/debug/DefaultDebugSupport.java | 8 +-
.../server/api/debug/RuntimeMeasurement.java | 106 ++++++++
lib/server-core/pom.xml | 10 +-
.../apache/olingo/server/core/ODataHandler.java | 31 ++-
.../server/core/ODataHttpHandlerImpl.java | 105 +++++++-
.../apache/olingo/server/core/ODataImpl.java | 2 +-
.../olingo/server/core/debug/DebugInfo.java | 50 ++++
.../olingo/server/core/debug/DebugInfoBody.java | 150 +++++++++++
.../server/core/debug/DebugInfoException.java | 142 +++++++++++
.../server/core/debug/DebugInfoRequest.java | 112 ++++++++
.../server/core/debug/DebugInfoResponse.java | 87 +++++++
.../server/core/debug/DebugInfoRuntime.java | 186 ++++++++++++++
.../server/core/debug/DebugInfoServer.java | 87 +++++++
.../olingo/server/core/debug/DebugInfoUri.java | 231 +++++++++++++++++
.../core/debug/DebugResponseHelperImpl.java | 255 ++++++++++++++++++-
lib/server-tecsvc/pom.xml | 1 -
lib/server-test/pom.xml | 1 -
20 files changed, 1556 insertions(+), 44 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataRequest.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataRequest.java
index ea48749..ed34e96 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataRequest.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataRequest.java
@@ -6,9 +6,9 @@
* 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
@@ -39,6 +39,7 @@ public class ODataRequest {
private String rawODataPath;
private String rawBaseUri;
private String rawServiceResolutionUri;
+ private String protocol;
/**
* Gets the HTTP method.
@@ -203,4 +204,21 @@ public class ODataRequest {
public void setRawServiceResolutionUri(final String rawServiceResolutionUri) {
this.rawServiceResolutionUri = rawServiceResolutionUri;
}
+
+ /**
+ * @return the protocol version used e.g. HTTP/1.1
+ */
+ public String getProtocol() {
+ return protocol;
+ }
+
+ /**
+ * Sets the HTTP protocol used
+ * @param protocol
+ * @see #getProtocol()
+ */
+ public void setProtocol(String protocol) {
+ this.protocol = protocol;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java
index 62a2d8a..bf6fc56 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java
@@ -18,6 +18,9 @@
*/
package org.apache.olingo.server.api.debug;
+import java.util.List;
+import java.util.Map;
+
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
@@ -31,8 +34,10 @@ public interface DebugResponseHelper {
* @param request
* @param applicationResponse
* @param exception
+ * @param serverEnvironmentVaribles
+ * @param runtimeInformation
* @return the debug response or the raw application response in case an exception occurred.
*/
- ODataResponse createDebugResponse(ODataRequest request, ODataResponse applicationResponse, Exception exception);
-
+ ODataResponse createDebugResponse(ODataRequest request, ODataResponse applicationResponse, Exception exception,
+ Map<String, String> serverEnvironmentVaribles, List<RuntimeMeasurement> runtimeInformation);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java
index 3ed39a5..995ba34 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java
@@ -18,6 +18,9 @@
*/
package org.apache.olingo.server.api.debug;
+import java.util.List;
+import java.util.Map;
+
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
@@ -44,6 +47,6 @@ public interface DebugSupport {
* @return a new debug response which will be send to the client
*/
ODataResponse createDebugResponse(String debugFormat, ODataRequest request, ODataResponse response,
- Exception exception);
+ Exception exception, Map<String, String> serverEnvironmentVaribles, List<RuntimeMeasurement> runtimeInformation);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java
index fb8851d..cca537f 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java
@@ -18,6 +18,9 @@
*/
package org.apache.olingo.server.api.debug;
+import java.util.List;
+import java.util.Map;
+
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
@@ -36,12 +39,13 @@ public class DefaultDebugSupport implements DebugSupport {
@Override
public ODataResponse createDebugResponse(String debugFormat, ODataRequest request, ODataResponse applicationResponse,
- Exception exception) {
+ Exception exception, Map<String, String> serverEnvironmentVaribles, List<RuntimeMeasurement> runtimeInformation) {
// Check if debugFormat is supported by the library
if (DebugSupport.ODATA_DEBUG_JSON.equalsIgnoreCase(debugFormat)
|| DebugSupport.ODATA_DEBUG_HTML.equalsIgnoreCase(debugFormat)
|| DebugSupport.ODATA_DEBUG_DOWNLOAD.equalsIgnoreCase(debugFormat)) {
- return odata.createDebugResponseHelper(debugFormat).createDebugResponse(request, applicationResponse, exception);
+ return odata.createDebugResponseHelper(debugFormat).createDebugResponse(request, applicationResponse, exception,
+ serverEnvironmentVaribles, runtimeInformation);
} else {
// Debug format is not supported by the library by default so in order to avoid an exception we will just give
// back the original response from the application.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/RuntimeMeasurement.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/RuntimeMeasurement.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/RuntimeMeasurement.java
new file mode 100644
index 0000000..69e30da
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/RuntimeMeasurement.java
@@ -0,0 +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.server.api.debug;
+
+/**
+ * <p>Runtime measurements.</p>
+ * <p>All times are in nanoseconds since some fixed but arbitrary time
+ * (perhaps in the future, so values may be negative).</p>
+ * @see System#nanoTime()
+ */
+public class RuntimeMeasurement {
+
+ private String className;
+ private String methodName;
+ private long timeStarted;
+ private long timeStopped;
+
+ /**
+ * Sets the class name.
+ * @param className the name of the class that is measured
+ */
+ public void setClassName(String className) {
+ this.className = className;
+ }
+
+ /**
+ * Gets the class name.
+ * @return the name of the class that is measured
+ */
+ public String getClassName() {
+ return className;
+ };
+
+ /**
+ * Sets the method name.
+ * @param methodName the name of the method that is measured
+ */
+ public void setMethodName(String methodName) {
+ this.methodName = methodName;
+ }
+
+ /**
+ * Gets the method name.
+ * @return the name of the method that is measured
+ */
+ public String getMethodName() {
+ return methodName;
+ }
+
+ /**
+ * Sets the start time.
+ * @param timeStarted the start time in nanoseconds
+ * @see System#nanoTime()
+ */
+ public void setTimeStarted(long timeStarted) {
+ this.timeStarted = timeStarted;
+ }
+
+ /**
+ * Gets the start time.
+ * @return the start time in nanoseconds or 0 if not set yet
+ * @see System#nanoTime()
+ */
+ public long getTimeStarted() {
+ return timeStarted;
+ }
+
+ /**
+ * Sets the stop time.
+ * @param timeStopped the stop time in nanoseconds
+ * @see System#nanoTime()
+ */
+ public void setTimeStopped(long timeStopped) {
+ this.timeStopped = timeStopped;
+ }
+
+ /**
+ * Gets the stop time.
+ * @return the stop time in nanoseconds or 0 if not set yet
+ * @see System#nanoTime()
+ */
+ public long getTimeStopped() {
+ return timeStopped;
+ }
+
+ @Override
+ public String toString() {
+ return className + "." + methodName + ": duration: " + (timeStopped - timeStarted);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-core/pom.xml
----------------------------------------------------------------------
diff --git a/lib/server-core/pom.xml b/lib/server-core/pom.xml
index 7d1758e..68c48a3 100644
--- a/lib/server-core/pom.xml
+++ b/lib/server-core/pom.xml
@@ -55,7 +55,10 @@
<version>2.5</version>
<scope>provided</scope>
</dependency>
-
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
<dependency>
<groupId>junit</groupId>
@@ -69,11 +72,6 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</dependency>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- <scope>test</scope>
- </dependency>
</dependencies>
<build>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
index 47bef3d..1a0df8d 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
@@ -58,6 +58,7 @@ public class ODataHandler {
private CustomETagSupport customETagSupport;
private UriInfo uriInfo;
+ private Exception lastThrownException;
public ODataHandler(final OData server, final ServiceMetadata serviceMetadata) {
odata = server;
@@ -75,37 +76,37 @@ public class ODataHandler {
} catch (final UriValidationException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
- handleException(request, response, serverError);
+ handleException(request, response, serverError, e);
} catch (final UriParserSemanticException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
- handleException(request, response, serverError);
+ handleException(request, response, serverError, e);
} catch (final UriParserSyntaxException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
- handleException(request, response, serverError);
+ handleException(request, response, serverError, e);
} catch (final UriParserException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
- handleException(request, response, serverError);
+ handleException(request, response, serverError, e);
} catch (ContentNegotiatorException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
- handleException(request, response, serverError);
+ handleException(request, response, serverError, e);
} catch (SerializerException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
- handleException(request, response, serverError);
+ handleException(request, response, serverError, e);
} catch (DeserializerException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
- handleException(request, response, serverError);
+ handleException(request, response, serverError, e);
} catch (PreconditionException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
- handleException(request, response, serverError);
+ handleException(request, response, serverError, e);
} catch (ODataHandlerException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
- handleException(request, response, serverError);
+ handleException(request, response, serverError, e);
} catch (ODataApplicationException e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e);
- handleException(request, response, serverError);
+ handleException(request, response, serverError, e);
} catch (Exception e) {
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e);
- handleException(request, response, serverError);
+ handleException(request, response, serverError, e);
}
return response;
}
@@ -124,8 +125,8 @@ public class ODataHandler {
}
public void handleException(final ODataRequest request, final ODataResponse response,
- final ODataServerError serverError) {
-
+ final ODataServerError serverError, Exception exception) {
+ this.lastThrownException = exception;
ErrorProcessor exceptionProcessor;
try {
exceptionProcessor = selectProcessor(ErrorProcessor.class);
@@ -187,4 +188,8 @@ public class ODataHandler {
public CustomETagSupport getCustomETagSupport() {
return customETagSupport;
}
+
+ public Exception getLastThrownException() {
+ return lastThrownException;
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
index 566086a..2bab186 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
@@ -24,7 +24,9 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
@@ -41,6 +43,7 @@ import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.debug.DebugSupport;
+import org.apache.olingo.server.api.debug.RuntimeMeasurement;
import org.apache.olingo.server.api.etag.CustomETagSupport;
import org.apache.olingo.server.api.processor.Processor;
import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
@@ -53,10 +56,17 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
private static final Logger LOG = LoggerFactory.getLogger(ODataHttpHandlerImpl.class);
private final ODataHandler handler;
- private DebugSupport debugSupport;
+ private final OData odata;
private int split = 0;
+ // debug stuff
+ private final List<RuntimeMeasurement> runtimeInformation = new ArrayList<RuntimeMeasurement>();
+ private DebugSupport debugSupport;
+ private String debugFormat;
+ private boolean isDebugMode = false;
+
public ODataHttpHandlerImpl(final OData odata, final ServiceMetadata serviceMetadata) {
+ this.odata = odata;
handler = new ODataHandler(odata, serviceMetadata);
}
@@ -65,31 +75,101 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
Exception exception = null;
ODataRequest odRequest = null;
ODataResponse odResponse;
+ resolveDebugMode(request);
+ int processMethodHandel = startRuntimeMeasurement("ODataHttpHandlerImpl", "process");
+
try {
odRequest = new ODataRequest();
+ int requestHandel = startRuntimeMeasurement("ODataHttpHandlerImpl", "fillODataRequest");
fillODataRequest(odRequest, request, split);
+ stopRuntimeMeasurement(requestHandel);
+
+ int responseHandel = startRuntimeMeasurement("ODataHandler", "process");
odResponse = handler.process(odRequest);
+ stopRuntimeMeasurement(responseHandel);
// ALL future methods after process must not throw exceptions!
} catch (Exception e) {
exception = e;
odResponse = handleException(odRequest, e);
}
-
- if (debugSupport != null) {
- String debugFormat = getDebugQueryParameter(request);
- if (debugFormat != null) {
- // TODO: Should we be more careful here with response assignement in order to not loose the original response?
- // TODO: How should we react to exceptions here?
- odResponse = debugSupport.createDebugResponse(debugFormat, odRequest, odResponse, exception);
+ stopRuntimeMeasurement(processMethodHandel);
+
+ if (isDebugMode) {
+ debugSupport.init(odata);
+ // TODO: Should we be more careful here with response assignement in order to not loose the original response?
+ // TODO: How should we react to exceptions here?
+ if (exception == null) {
+ // This is to ensure that we have access to the thrown OData Exception
+ // TODO: Should we make this hack
+ exception = handler.getLastThrownException();
}
+ Map<String, String> serverEnvironmentVaribles = createEnvironmentVariablesMap(request);
+
+ odResponse =
+ debugSupport.createDebugResponse(debugFormat, odRequest, odResponse, exception, serverEnvironmentVaribles,
+ runtimeInformation);
}
convertToHttp(response, odResponse);
}
- private String getDebugQueryParameter(HttpServletRequest request) {
- // TODO Auto-generated method stub
- return "";
+ private void resolveDebugMode(HttpServletRequest request) {
+ if (debugSupport != null) {
+ // Should we read the parameter from the servlet here and ignore multiple parameters?
+ debugFormat = request.getParameter(DebugSupport.ODATA_DEBUG_QUERY_PARAMETER);
+ // Debug format is present and we have a debug support processor registered so we are in debug mode
+ isDebugMode = debugFormat != null;
+ }
+ }
+
+ public int startRuntimeMeasurement(final String className, final String methodName) {
+ if (isDebugMode) {
+ int handleId = runtimeInformation.size();
+
+ final RuntimeMeasurement measurement = new RuntimeMeasurement();
+ measurement.setTimeStarted(System.nanoTime());
+ measurement.setClassName(className);
+ measurement.setMethodName(methodName);
+
+ runtimeInformation.add(measurement);
+
+ return handleId;
+ } else {
+ return 0;
+ }
+ }
+
+ public void stopRuntimeMeasurement(final int handle) {
+ if (isDebugMode && handle < runtimeInformation.size()) {
+ long stopTime = System.nanoTime();
+ RuntimeMeasurement runtimeMeasurement = runtimeInformation.get(handle);
+ if (runtimeMeasurement != null) {
+ runtimeMeasurement.setTimeStopped(stopTime);
+ }
+ }
+ }
+
+ private Map<String, String> createEnvironmentVariablesMap(HttpServletRequest request) {
+ LinkedHashMap<String, String> environment = new LinkedHashMap<String, String>();
+ environment.put("authType", request.getAuthType());
+ environment.put("localAddr", request.getLocalAddr());
+ environment.put("localName", request.getLocalName());
+ environment.put("localPort", getIntAsString(request.getLocalPort()));
+ environment.put("pathInfo", request.getPathInfo());
+ environment.put("pathTranslated", request.getPathTranslated());
+ environment.put("remoteAddr", request.getRemoteAddr());
+ environment.put("remoteHost", request.getRemoteHost());
+ environment.put("remotePort", getIntAsString(request.getRemotePort()));
+ environment.put("remoteUser", request.getRemoteUser());
+ environment.put("scheme", request.getScheme());
+ environment.put("serverName", request.getServerName());
+ environment.put("serverPort", getIntAsString(request.getServerPort()));
+ environment.put("servletPath", request.getServletPath());
+ return environment;
+ }
+
+ private String getIntAsString(final int number) {
+ return number == 0 ? "unknown" : Integer.toString(number);
}
@Override
@@ -107,7 +187,7 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
} else {
serverError = ODataExceptionHelper.createServerErrorObject(e);
}
- handler.handleException(odRequest, resp, serverError);
+ handler.handleException(odRequest, resp, serverError, e);
return resp;
}
@@ -153,6 +233,7 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
throws ODataLibraryException {
try {
odRequest.setBody(httpRequest.getInputStream());
+ odRequest.setProtocol(httpRequest.getProtocol());
extractHeaders(odRequest, httpRequest);
extractUri(odRequest, httpRequest, split);
extractMethod(odRequest, httpRequest);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
index dac1642..d1da556 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
@@ -145,7 +145,7 @@ public class ODataImpl extends OData {
public DebugResponseHelper createDebugResponseHelper(String debugFormat) {
//TODO: What should we do with invalid formats?
//TODO: Support more debug formats
- return new DebugResponseHelperImpl();
+ return new DebugResponseHelperImpl(debugFormat);
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfo.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfo.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfo.java
new file mode 100644
index 0000000..9c5a1d4
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfo.java
@@ -0,0 +1,50 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+
+/**
+ * Debug information.
+ */
+public interface DebugInfo {
+
+ /**
+ * Gets the name of this debug information part, useful as title.
+ * @return the name
+ */
+ public String getName();
+
+ /**
+ * Appends the content of this debug information part
+ * to the given JSON stream writer.
+ * @param jsonGenerator a JSON generator
+ */
+ public void appendJson(JsonGenerator jsonGenerator) throws IOException;
+
+ /**
+ * Appends the content of this debug information part to the given writer.
+ * @param writer a {@link Writer}
+ */
+ public void appendHtml(Writer writer) throws IOException;
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoBody.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoBody.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoBody.java
new file mode 100644
index 0000000..e266aae
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoBody.java
@@ -0,0 +1,150 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.server.api.ODataResponse;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+/**
+ * Response body debug information.
+ */
+public class DebugInfoBody implements DebugInfo {
+
+ private static enum ResponseContent {JSON, XML, TEXT, IMAGE};
+
+ private final ODataResponse response;
+ private final ResponseContent responseContent;
+
+ //private final String serviceRoot;
+// private final boolean isXml;
+// private final boolean isJson;
+// private final boolean isText;
+// private final boolean isImage;
+
+ public DebugInfoBody(final ODataResponse response, final String serviceRoot) {
+ this.response = response;
+ // TODO: make header case insensitive
+ final String contentType = response.getHeaders().get(HttpHeader.CONTENT_TYPE);
+ //TODO: Differentiate better
+ if (contentType != null) {
+ responseContent = ResponseContent.JSON;
+ } else {
+ responseContent = ResponseContent.TEXT;
+ }
+// isXml = contentType.contains("xml");
+// isJson = !isXml && contentType.startsWith(HttpContentType.APPLICATION_JSON);
+// isText = isXml || isJson || contentType.startsWith("text/")
+// || contentType.startsWith(HttpContentType.APPLICATION_HTTP)
+// || contentType.startsWith(HttpContentType.MULTIPART_MIXED);
+// isImage = !isText && contentType.startsWith("image/");
+ }
+
+ @Override
+ public String getName() {
+ return "Body";
+ }
+
+//
+ @Override
+ public void appendJson(final JsonGenerator gen) throws IOException {
+ gen.writeString(getContentString());
+ }
+
+ private String getContentString() {
+ try {
+ String contentString;
+ switch (responseContent) {
+ case IMAGE:
+ //TODO: DecodeString as base 64
+ contentString = "Currently not supported";
+ break;
+ case JSON:
+ case XML:
+ case TEXT:
+ default:
+ // TODO: Remove IOUtils from core dependency
+ contentString = IOUtils.toString(response.getContent(), "UTF-8");
+ break;
+ }
+ return contentString;
+ } catch (IOException e) {
+ return "Could not parse Body for Debug Output";
+ }
+ }
+
+//
+// @Override
+// public void appendHtml(final Writer writer) throws IOException {
+// final String body = getContentString();
+// if (isImage) {
+// writer.append("<img src=\"data:").append(response.getContentHeader()).append(";base64,")
+// .append(body)
+// .append("\" />\n");
+// } else {
+// writer.append("<pre class=\"code").append(isXml ? " xml" : isJson ? " json" : "").append("\">\n")
+// .append(isXml || isJson ?
+// addLinks(ODataDebugResponseWrapper.escapeHtml(isXml ? formatXml(body) : formatJson(body)), isXml) :
+// ODataDebugResponseWrapper.escapeHtml(body))
+// .append("</pre>\n");
+// }
+// }
+//
+// private String formatXml(final String xml) throws IOException {
+// try {
+// Transformer transformer = TransformerFactory.newInstance().newTransformer();
+// transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+// transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+// StreamResult outputTarget = new StreamResult(new StringWriter());
+// transformer.transform(new StreamSource(new StringReader(xml)), outputTarget);
+// return outputTarget.getWriter().toString();
+// } catch (final TransformerException e) {
+// return xml;
+// }
+// }
+//
+// private String formatJson(final String json) {
+// return new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create().toJson(new JsonParser().parse(json));
+// }
+//
+// private String addLinks(final String source, final boolean isXml) {
+// final String debugOption = ODataDebugResponseWrapper.ODATA_DEBUG_QUERY_PARAMETER + "="
+// + ODataDebugResponseWrapper.ODATA_DEBUG_HTML;
+// final String urlPattern = "("
+// + (isXml ? "(?:href|src|base)=" : "\"(?:uri|media_src|edit_media|__next)\":\\p{Space}*")
+// + "\")(.+?)\"";
+// return (isXml ? source.replaceAll("(xmlns(?::\\p{Alnum}+)?=\")(.+?)\"", "$1<span class=\"ns\">$2</span>\"") :
+// source)
+// .replaceAll(urlPattern, "$1<a href=\"" + serviceRoot + "$2?" + debugOption + "\">$2</a>\"")
+// .replaceAll("(<a href=\"" + Pattern.quote(serviceRoot) + ')' + Pattern.quote(serviceRoot), "$1")
+// .replaceAll("<a href=\"(.+?)\\?(.+?)\\?" + debugOption, "<a href=\"$1?$2&" + debugOption)
+// .replaceAll("&amp;", "&");
+// }
+
+ @Override
+ public void appendHtml(Writer writer) throws IOException {
+ // TODO Auto-generated method stub
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoException.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoException.java
new file mode 100644
index 0000000..b19252f
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoException.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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.olingo.server.api.ODataLibraryException;
+import org.apache.olingo.server.api.ODataLibraryException.ODataErrorMessage;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+/**
+ * Exception debug information.
+ */
+public class DebugInfoException implements DebugInfo {
+
+ private final Exception exception;
+
+ public DebugInfoException(final Exception exception) {
+ this.exception = exception;
+ }
+
+ @Override
+ public String getName() {
+ return "Stacktrace";
+ }
+
+ @Override
+ public void appendJson(final JsonGenerator gen) throws IOException {
+ gen.writeStartObject();
+ gen.writeFieldName("exceptions");
+ gen.writeStartArray();
+ Throwable throwable = exception;
+ while (throwable != null) {
+ gen.writeStartObject();
+ gen.writeStringField("class", throwable.getClass().getCanonicalName());
+ gen.writeStringField("message", getMessage(throwable));
+ gen.writeFieldName("invocation");
+ appendJsonStackTraceElement(gen, throwable.getStackTrace()[0]);
+ gen.writeEndObject();
+
+ // Get next exception in the cause list
+ throwable = throwable.getCause();
+ }
+ gen.writeEndArray();
+
+ gen.writeFieldName("stacktrace");
+ gen.writeStartArray();
+ for (final StackTraceElement stackTraceElement : exception.getStackTrace()) {
+ appendJsonStackTraceElement(gen, stackTraceElement);
+ }
+ gen.writeEndArray();
+
+ gen.writeEndObject();
+ }
+
+ private String getMessage(final Throwable throwable) {
+ String message;
+ if (throwable instanceof ODataLibraryException) {
+ ODataLibraryException ex = (ODataLibraryException) throwable;
+ // We use the default locale
+ ODataErrorMessage translatedMessage = ex.getTranslatedMessage(null);
+ // We provide the best message we can
+ message = translatedMessage.getMessage() == null ? ex.getMessage() : translatedMessage.getMessage();
+ } else {
+ message = throwable.getMessage();
+ }
+ return message;
+ }
+
+ private void appendJsonStackTraceElement(final JsonGenerator gen, final StackTraceElement element)
+ throws IOException {
+ gen.writeStartObject();
+ gen.writeStringField("class", element.getClassName());
+ gen.writeStringField("method", element.getMethodName());
+ gen.writeStringField("line", Integer.toString(element.getLineNumber()));
+ gen.writeEndObject();
+ }
+
+ @Override
+ public void appendHtml(Writer writer) throws IOException {
+ // TODO Auto-generated method stub
+
+ }
+//
+// @Override
+// public void appendHtml(final Writer writer) throws IOException {
+// appendException(exception, writer);
+// writer.append("<h2>Stacktrace</h2>\n");
+// int count = 0;
+// for (final StackTraceElement stackTraceElement : exception.getStackTrace()) {
+// appendStackTraceElement(stackTraceElement, ++count == 1, count == exception.getStackTrace().length, writer);
+// }
+// }
+//
+// private void appendException(final Throwable throwable, final Writer writer) throws IOException {
+// if (throwable.getCause() != null) {
+// appendException(throwable.getCause(), writer);
+// }
+// final StackTraceElement details = throwable.getStackTrace()[0];
+// writer.append("<h2>").append(throwable.getClass().getCanonicalName()).append("</h2>\n")
+// .append("<p>")
+// .append(ODataDebugResponseWrapper.escapeHtml(getMessageText(throwable)))
+// .append("</p>\n");
+// appendStackTraceElement(details, true, true, writer);
+// }
+//
+// private void appendStackTraceElement(final StackTraceElement stackTraceElement,
+// final boolean isFirst, final boolean isLast, final Writer writer) throws IOException {
+// if (isFirst) {
+// writer.append("<table>\n<thead>\n")
+// .append("<tr>\n<th class=\"name\">Class</th>\n")
+// .append("<th class=\"name\">Method</th>\n")
+// .append("<th class=\"value\">Line number in class</th>\n</tr>\n")
+// .append("</thead>\n<tbody>\n");
+// }
+// writer.append("<tr>\n<td class=\"name\">").append(stackTraceElement.getClassName()).append("</td>\n")
+// .append("<td class=\"name\">").append(stackTraceElement.getMethodName()).append("</td>\n")
+// .append("<td class=\"value\">").append(Integer.toString(stackTraceElement.getLineNumber()))
+// .append("</td>\n</tr>\n");
+// if (isLast) {
+// writer.append("</tbody>\n</table>\n");
+// }
+// }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRequest.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRequest.java
new file mode 100644
index 0000000..e28bbb9
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRequest.java
@@ -0,0 +1,112 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.server.api.ODataRequest;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+/**
+ * Request debug information.
+ */
+public class DebugInfoRequest implements DebugInfo {
+
+ private final String method;
+ private final String uri;
+ private final String protocol;
+ private final Map<String, String> headers;
+
+ public DebugInfoRequest(ODataRequest request) {
+ method = request.getMethod() == null ? "unkown" : request.getMethod().toString();
+ uri = request.getRawRequestUri() == null ? "unkown" : request.getRawRequestUri();
+ protocol = request.getProtocol() == null ? "unkown" : request.getProtocol();
+ // TODO: Should we really wrap the headers here or keep the original structure?
+ headers = wrapHeaders(request.getAllHeaders());
+ }
+
+ private Map<String, String> wrapHeaders(Map<String, List<String>> allHeaders) {
+ Map<String, String> localHeaders = new HashMap<String, String>();
+ for (Map.Entry<String, List<String>> entry : allHeaders.entrySet()) {
+ String value = null;
+ if (entry.getValue() != null) {
+ value = "";
+ boolean first = true;
+ for (String valuePart : entry.getValue()) {
+ if (!first) {
+ value = value + ", ";
+ }
+ value = value + valuePart;
+ }
+ }
+ }
+ return localHeaders;
+ }
+
+ @Override
+ public void appendHtml(final Writer writer) throws IOException {
+// writer.append("<h2>Request Method</h2>\n")
+// .append("<p>").append(method).append("</p>\n")
+// .append("<h2>Request URI</h2>\n")
+// .append("<p>").append(DebugResponseHelperImpl.escapeHtml(uri.toString())).append("</p>\n")
+// .append("<h2>Request Protocol</h2>\n")
+// .append("<p>").append(protocol).append("</p>\n");
+// writer.append("<h2>Request Headers</h2>\n")
+// .append("<table>\n<thead>\n")
+// .append("<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n")
+// .append("</thead>\n<tbody>\n");
+// for (final String name : headers.keySet()) {
+// for (final String value : headers.get(name)) {
+// if (value != null) {
+// writer.append("<tr><td class=\"name\">").append(name).append("</td>")
+// .append("<td class=\"value\">").append(DebugResponseHelperImpl.escapeHtml(value))
+// .append("</td></tr>\n");
+// }
+// }
+// }
+// writer.append("</tbody>\n</table>\n");
+ }
+
+ @Override
+ public String getName() {
+ return "Request";
+ }
+
+ @Override
+ public void appendJson(JsonGenerator gen) throws IOException {
+ gen.writeStartObject();
+ gen.writeStringField("method", method);
+
+ gen.writeStringField("uri", uri);
+
+ gen.writeStringField("protocol", protocol);
+
+ if (!headers.isEmpty()) {
+ gen.writeFieldName("headers");
+ DebugResponseHelperImpl.appendJsonTable(gen, headers);
+ }
+
+ gen.writeEndObject();
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoResponse.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoResponse.java
new file mode 100644
index 0000000..0781d50
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoResponse.java
@@ -0,0 +1,87 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Map;
+
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.ODataResponse;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+/**
+ * Response debug information.
+ */
+public class DebugInfoResponse implements DebugInfo {
+
+ private final ODataResponse response;
+ private final String serviceRoot;
+ private final HttpStatusCode status;
+ private final Map<String, String> headers;
+
+ public DebugInfoResponse(final ODataResponse applicationResponse, final String serviceRoot) {
+ this.response = applicationResponse;
+ this.serviceRoot = serviceRoot;
+ status = HttpStatusCode.fromStatusCode(response.getStatusCode());
+ headers = response.getHeaders();
+ }
+
+ @Override
+ public String getName() {
+ return "Response";
+ }
+
+ @Override
+ public void appendJson(final JsonGenerator gen) throws IOException {
+ gen.writeStartObject();
+
+ if (status != null) {
+ gen.writeFieldName("status");
+ gen.writeStartObject();
+ gen.writeStringField("code", Integer.toString(status.getStatusCode()));
+ gen.writeStringField("info", status.getInfo());
+ gen.writeEndObject();
+ }
+
+ if (headers != null && !headers.isEmpty()) {
+ gen.writeFieldName("headers");
+ DebugResponseHelperImpl.appendJsonTable(gen, headers);
+ }
+
+ gen.writeFieldName("body");
+ new DebugInfoBody(response, serviceRoot).appendJson(gen);
+
+ gen.writeEndObject();
+ }
+
+ @Override
+ public void appendHtml(final Writer writer) throws IOException {
+// writer.append("<h2>Status Code</h2>\n")
+// .append("<p>").append(Integer.toString(status.getStatusCode())).append(' ')
+// .append(status.getInfo()).append("</p>\n")
+// .append("<h2>Response Headers</h2>\n");
+// ODataDebugResponseWrapper.appendHtmlTable(writer, headers);
+// if (response.getContentHeader() != null && response.getEntity() != null) {
+// writer.append("<h2>Response Body</h2>\n");
+// new DebugInfoBody(response, serviceRoot).appendHtml(writer);
+// }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRuntime.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRuntime.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRuntime.java
new file mode 100644
index 0000000..2465ce4
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRuntime.java
@@ -0,0 +1,186 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.olingo.server.api.debug.RuntimeMeasurement;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+/**
+ * Runtime debug information.
+ */
+public class DebugInfoRuntime implements DebugInfo {
+
+ private final RuntimeNode rootNode;
+
+ public DebugInfoRuntime(List<RuntimeMeasurement> runtimeInformation) {
+ rootNode = new RuntimeNode();
+ for (final RuntimeMeasurement runtimeMeasurement : runtimeInformation) {
+ rootNode.add(runtimeMeasurement);
+ }
+ rootNode.combineRuntimeMeasurements();
+ }
+
+ @Override
+ public String getName() {
+ return "Runtime";
+ }
+
+ @Override
+ public void appendJson(JsonGenerator gen) throws IOException {
+ appendJsonChildren(gen, rootNode);
+ }
+
+ private void appendJsonChildren(JsonGenerator gen, RuntimeNode node) throws IOException {
+ gen.writeStartArray();
+ for (RuntimeNode child : node.children) {
+ appendJsonNode(gen, child);
+ }
+ gen.writeEndArray();
+ }
+
+ private void appendJsonNode(JsonGenerator gen, RuntimeNode node) throws IOException {
+ gen.writeStartObject();
+ gen.writeStringField("class", node.className);
+ gen.writeStringField("method ", node.methodName);
+
+ if (node.timeStopped == 0) {
+ gen.writeNullField("duration");
+ } else {
+ gen.writeStringField("duration", Long.toString((node.timeStopped - node.timeStarted) / 1000));
+ gen.writeStringField("unit", "µs");
+ }
+
+ if (!node.children.isEmpty()) {
+ gen.writeFieldName("children");
+ appendJsonChildren(gen, node);
+ }
+
+ gen.writeEndObject();
+ }
+
+ @Override
+ public void appendHtml(Writer writer) throws IOException {
+ // TODO Auto-generated method stub
+ //
+// @Override
+// public void appendHtml(final Writer writer) throws IOException {
+// appendRuntimeNode(rootNode, "", true, writer);
+// }
+//
+// private void appendRuntimeNode(final RuntimeNode node, final String draw, final boolean isLast, final Writer writer)
+// throws IOException {
+// if (node.className != null) {
+// writer.append("<li>")
+// .append("<span class=\"code\">")
+// .append("<span class=\"draw\">").append(draw)
+// .append(isLast ? "└" : "├").append("─ </span>")
+// .append("<span class=\"class\">").append(node.className).append("</span>.")
+// .append("<span class=\"method\">").append(node.methodName).append("(…)")
+// .append("</span></span>");
+// long time = node.timeStopped == 0 ? 0 : (node.timeStopped - node.timeStarted) / 1000;
+// writer.append("<span class=\"").append(time == 0 ? "null" : "numeric")
+// .append("\" title=\"").append(time == 0 ? "Stop time missing" : "Gross duration")
+// .append("\">").append(time == 0 ? "unfinished" : Long.toString(time) + " µs")
+// .append("</span>\n");
+// }
+// if (!node.children.isEmpty()) {
+// writer.append("<ol class=\"tree\">\n");
+// for (final RuntimeNode childNode : node.children) {
+// appendRuntimeNode(childNode,
+// node.className == null ? draw : draw + (isLast ? " " : "│") + " ",
+// node.children.indexOf(childNode) == node.children.size() - 1,
+// writer);
+// }
+// writer.append("</ol>\n");
+// }
+// if (node.className != null) {
+// writer.append("</li>\n");
+// }
+// }
+ }
+
+ private class RuntimeNode {
+
+ protected String className;
+ protected String methodName;
+ protected long timeStarted;
+ protected long timeStopped;
+ protected List<RuntimeNode> children = new ArrayList<RuntimeNode>();
+
+ protected RuntimeNode() {
+ timeStarted = 0;
+ timeStopped = Long.MAX_VALUE;
+ }
+
+ private RuntimeNode(final RuntimeMeasurement runtimeMeasurement) {
+ className = runtimeMeasurement.getClassName();
+ methodName = runtimeMeasurement.getMethodName();
+ timeStarted = runtimeMeasurement.getTimeStarted();
+ timeStopped = runtimeMeasurement.getTimeStopped();
+ }
+
+ protected boolean add(final RuntimeMeasurement runtimeMeasurement) {
+ if (timeStarted <= runtimeMeasurement.getTimeStarted()
+ && timeStopped != 0 && timeStopped >= runtimeMeasurement.getTimeStopped()) {
+ for (RuntimeNode candidate : children) {
+ if (candidate.add(runtimeMeasurement)) {
+ return true;
+ }
+ }
+ children.add(new RuntimeNode(runtimeMeasurement));
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Combines runtime measurements with identical class names and method
+ * names into one measurement, assuming that they originate from a loop
+ * or a similar construct where a summary measurement has been intended.
+ */
+ protected void combineRuntimeMeasurements() {
+ RuntimeNode preceding = null;
+ for (Iterator<RuntimeNode> iterator = children.iterator(); iterator.hasNext();) {
+ final RuntimeNode child = iterator.next();
+ if (preceding != null
+ && preceding.timeStopped != 0 && child.timeStopped != 0
+ && preceding.timeStopped <= child.timeStarted
+ && preceding.children.isEmpty() && child.children.isEmpty()
+ && preceding.methodName.equals(child.methodName)
+ && preceding.className.equals(child.className)) {
+ preceding.timeStarted = child.timeStarted - (preceding.timeStopped - preceding.timeStarted);
+ preceding.timeStopped = child.timeStopped;
+
+ iterator.remove();
+ } else {
+ preceding = child;
+ child.combineRuntimeMeasurements();
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoServer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoServer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoServer.java
new file mode 100644
index 0000000..e974d03
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoServer.java
@@ -0,0 +1,87 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+/**
+ * Server debug information.
+ */
+public class DebugInfoServer implements DebugInfo {
+
+ private final Map<String, String> serverEnvironmentVaribles;
+
+ public DebugInfoServer(Map<String, String> serverEnvironmentVaribles) {
+ this.serverEnvironmentVaribles = serverEnvironmentVaribles;
+ }
+
+ @Override
+ public String getName() {
+ return "Environment";
+ }
+
+ @Override
+ public void appendJson(JsonGenerator gen) throws IOException {
+ DebugResponseHelperImpl.appendJsonTable(gen, serverEnvironmentVaribles);
+ }
+
+ @Override
+ public void appendHtml(Writer writer) throws IOException {
+ // TODO Auto-generated method stub
+
+ }
+
+// private final Map<String, String> environment;
+//
+// public DebugInfoServer(final HttpServletRequest httpServletRequest) {
+// environment = new TreeMap<String, String>();
+// environment.put("authType", httpServletRequest.getAuthType());
+// environment.put("localAddr", httpServletRequest.getLocalAddr());
+// environment.put("localName", httpServletRequest.getLocalName());
+// addInt("localPort", httpServletRequest.getLocalPort());
+// environment.put("pathInfo", httpServletRequest.getPathInfo());
+// environment.put("pathTranslated", httpServletRequest.getPathTranslated());
+// environment.put("remoteAddr", httpServletRequest.getRemoteAddr());
+// environment.put("remoteHost", httpServletRequest.getRemoteHost());
+// addInt("remotePort", httpServletRequest.getRemotePort());
+// environment.put("remoteUser", httpServletRequest.getRemoteUser());
+// environment.put("scheme", httpServletRequest.getScheme());
+// environment.put("serverName", httpServletRequest.getServerName());
+// addInt("serverPort", httpServletRequest.getServerPort());
+// environment.put("servletPath", httpServletRequest.getServletPath());
+// }
+
+// @Override
+// public void appendHtml(final Writer writer) throws IOException {
+// final Package pack = ODataDebugResponseWrapper.class.getPackage();
+// writer.append("<h2>Library Version</h2>\n")
+// .append("<p>").append(pack.getImplementationTitle())
+// .append(" Version ").append(pack.getImplementationVersion()).append("</p>\n")
+// .append("<h2>Server Environment</h2>\n");
+// ODataDebugResponseWrapper.appendHtmlTable(writer, environment);
+// }
+//
+// private void addInt(final String name, final int number) {
+// environment.put(name, number == 0 ? null : Integer.toString(number));
+// }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoUri.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoUri.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoUri.java
new file mode 100644
index 0000000..2ddeb07
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoUri.java
@@ -0,0 +1,231 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+
+/**
+ * URI parser debug information.
+ */
+public class DebugInfoUri implements DebugInfo {
+
+ @Override
+ public String getName() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void appendJson(JsonGenerator jsonGenerator) throws IOException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void appendHtml(Writer writer) throws IOException {
+ // TODO Auto-generated method stub
+
+ }
+
+// private final UriInfo uriInfo;
+// private final FilterExpression filter;
+// private final OrderByExpression orderBy;
+// private final ExpandSelectTreeNodeImpl expandSelectTree;
+// private final ExpressionParserException exception;
+//
+// public DebugInfoUri(final UriInfo uriInfo, final ExpressionParserException exception) {
+// this.uriInfo = uriInfo;
+// filter = uriInfo == null ? null : uriInfo.getFilter();
+// orderBy = uriInfo == null ? null : uriInfo.getOrderBy();
+// expandSelectTree = uriInfo == null ? null : getExpandSelect();
+// this.exception = exception;
+// }
+//
+// private ExpandSelectTreeNodeImpl getExpandSelect() {
+// try {
+// return uriInfo.getExpand().isEmpty() && uriInfo.getSelect().isEmpty() ? null :
+// new ExpandSelectTreeCreator(uriInfo.getSelect(), uriInfo.getExpand()).create();
+// } catch (final EdmException e) {
+// return null;
+// }
+// }
+//
+// @Override
+// public String getName() {
+// return "URI";
+// }
+//
+// @Override
+// public void appendJson(final JsonStreamWriter jsonStreamWriter) throws IOException {
+// jsonStreamWriter.beginObject();
+//
+// if (exception != null && exception.getFilterTree() != null) {
+// jsonStreamWriter.name("error")
+// .beginObject()
+// .namedStringValue("expression", exception.getFilterTree().getUriLiteral())
+// .endObject();
+// if (filter != null || orderBy != null || expandSelectTree != null) {
+// jsonStreamWriter.separator();
+// }
+// }
+//
+// if (filter != null) {
+// String filterString;
+// try {
+// filterString = (String) filter.accept(new JsonVisitor());
+// } catch (final ExceptionVisitExpression e) {
+// filterString = null;
+// } catch (final ODataApplicationException e) {
+// filterString = null;
+// }
+// jsonStreamWriter.name("filter").unquotedValue(filterString);
+// if (orderBy != null || expandSelectTree != null) {
+// jsonStreamWriter.separator();
+// }
+// }
+//
+// if (orderBy != null) {
+// String orderByString;
+// try {
+// orderByString = (String) orderBy.accept(new JsonVisitor());
+// } catch (final ExceptionVisitExpression e) {
+// orderByString = null;
+// } catch (final ODataApplicationException e) {
+// orderByString = null;
+// }
+// jsonStreamWriter.name("orderby").unquotedValue(orderByString);
+// if (expandSelectTree != null) {
+// jsonStreamWriter.separator();
+// }
+// }
+//
+// if (expandSelectTree != null) {
+// jsonStreamWriter.name("expandSelect").unquotedValue(expandSelectTree.toJsonString());
+// }
+//
+// jsonStreamWriter.endObject();
+// }
+//
+// @Override
+// public void appendHtml(final Writer writer) throws IOException {
+// if (exception != null && exception.getFilterTree() != null) {
+// writer.append("<h2>Expression Information</h2>\n")
+// .append("<pre class=\"code\">").append(exception.getFilterTree().getUriLiteral())
+// .append("</pre>\n");
+// // TODO: filter error position, filter tokens, filter tree
+// }
+// if (filter != null) {
+// writer.append("<h2>Filter</h2>\n")
+// .append("<ul class=\"expr\"><li>");
+// appendExpression(filter.getExpression(), writer);
+// writer.append("</li></ul>\n");
+// }
+// if (orderBy != null) {
+// writer.append("<h2>Orderby</h2>\n")
+// .append(orderBy.getOrdersCount() == 1 ? "<ul" : "<ol").append(" class=\"expr\">\n");
+// for (final OrderExpression order : orderBy.getOrders()) {
+// writer.append("<li>");
+// appendExpression(order.getExpression(), writer);
+// final ExpressionKind kind = order.getExpression().getKind();
+// if (kind == ExpressionKind.PROPERTY || kind == ExpressionKind.LITERAL) {
+// writer.append("<br />");
+// }
+// writer.append("<span class=\"order\">")
+// .append(order.getSortOrder().toString())
+// .append("</span></li>\n");
+// }
+// writer.append(orderBy.getOrdersCount() == 1 ? "</ul" : "</ol").append(">\n");
+// }
+// if (expandSelectTree != null) {
+// writer.append("<h2>Expand/Select</h2>\n");
+// appendExpandSelect(expandSelectTree, writer);
+// }
+// }
+//
+// private void appendExpression(final CommonExpression expression, final Writer writer) throws IOException {
+// final ExpressionKind kind = expression.getKind();
+// writer.append("<span class=\"kind\">")
+// .append(kind.toString())
+// .append("</span> <span class=\"literal\">")
+// .append(kind == ExpressionKind.MEMBER ? ((MemberExpression) expression).getProperty().getUriLiteral() :
+// expression.getUriLiteral())
+// .append("</span>, type <span class=\"type\">")
+// .append(expression.getEdmType().toString())
+// .append("</span>");
+// if (kind == ExpressionKind.UNARY) {
+// writer.append("<ul class=\"expr\"><li>");
+// appendExpression(((UnaryExpression) expression).getOperand(), writer);
+// writer.append("</li></ul>");
+// } else if (kind == ExpressionKind.BINARY) {
+// writer.append("<ol class=\"expr\"><li>");
+// appendExpression(((BinaryExpression) expression).getLeftOperand(), writer);
+// writer.append("</li><li>");
+// appendExpression(((BinaryExpression) expression).getRightOperand(), writer);
+// writer.append("</li></ol>");
+// } else if (kind == ExpressionKind.METHOD) {
+// final MethodExpression methodExpression = (MethodExpression) expression;
+// if (methodExpression.getParameterCount() > 0) {
+// writer.append("<ol class=\"expr\">");
+// for (final CommonExpression parameter : methodExpression.getParameters()) {
+// writer.append("<li>");
+// appendExpression(parameter, writer);
+// writer.append("</li>");
+// }
+// writer.append("</ol>");
+// }
+// } else if (kind == ExpressionKind.MEMBER) {
+// writer.append("<ul class=\"expr\"><li>");
+// appendExpression(((MemberExpression) expression).getPath(), writer);
+// writer.append("</li></ul>");
+// }
+// }
+//
+// private void appendExpandSelect(final ExpandSelectTreeNode expandSelect, final Writer writer) throws IOException {
+// writer.append("<ul class=\"expand\">\n")
+// .append("<li>");
+// if (expandSelect.isAll()) {
+// writer.append("all properties");
+// } else {
+// for (final EdmProperty property : expandSelect.getProperties()) {
+// try {
+// writer.append("property <span class=\"prop\">")
+// .append(property.getName())
+// .append("</span><br />");
+// } catch (final EdmException e) {}
+// }
+// }
+// writer.append("</li>\n");
+// if (!expandSelect.getLinks().isEmpty()) {
+// for (final String name : expandSelect.getLinks().keySet()) {
+// writer.append("<li>link <span class=\"link\">").append(name).append("</span>");
+// final ExpandSelectTreeNode link = expandSelect.getLinks().get(name);
+// if (link != null) {
+// writer.append('\n');
+// appendExpandSelect(link, writer);
+// }
+// writer.append("</li>\n");
+// }
+// }
+// writer.append("</ul>\n");
+// }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java
index ca4d7f3..6952018 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java
@@ -18,16 +18,265 @@
*/
package org.apache.olingo.server.core.debug;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.olingo.commons.api.ODataRuntimeException;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.debug.DebugResponseHelper;
+import org.apache.olingo.server.api.debug.DebugSupport;
+import org.apache.olingo.server.api.debug.RuntimeMeasurement;
+import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
+
+import com.fasterxml.jackson.core.JsonEncoding;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
public class DebugResponseHelperImpl implements DebugResponseHelper {
+ private static enum DebugFormat {
+ JSON, HTML, DOWNLOAD
+ };
+
+ private final DebugFormat requestedFormat;
+
+ public DebugResponseHelperImpl(String debugFormat) {
+ if (DebugSupport.ODATA_DEBUG_HTML.equals(debugFormat)) {
+ requestedFormat = DebugFormat.HTML;
+ } else if (DebugSupport.ODATA_DEBUG_DOWNLOAD.equals(debugFormat)) {
+ requestedFormat = DebugFormat.DOWNLOAD;
+ } else {
+ requestedFormat = DebugFormat.JSON;
+ }
+ }
+
@Override
- public ODataResponse
- createDebugResponse(ODataRequest request, ODataResponse applicationResponse, Exception exception) {
- return applicationResponse;
+ public ODataResponse createDebugResponse(ODataRequest request, ODataResponse applicationResponse,
+ Exception exception, Map<String, String> serverEnvironmentVaribles, List<RuntimeMeasurement> runtimeInformation) {
+
+ try {
+ final List<DebugInfo> parts =
+ createParts(request, applicationResponse, exception, serverEnvironmentVaribles, runtimeInformation);
+
+ ODataResponse response = new ODataResponse();
+ String contentTypeString;
+ InputStream body;
+ switch (requestedFormat) {
+ case DOWNLOAD:
+ response.setHeader("Content-Disposition", "attachment; filename=OData-Response."
+ + new Date().toString().replace(' ', '_').replace(':', '.') + ".html");
+ // Download is the same as html except for the above header
+ case HTML:
+ body = wrapInHtml(parts);
+ contentTypeString = ContentType.TEXT_HTML.toContentTypeString();
+ break;
+ case JSON:
+ default:
+ body = wrapInJson(parts);
+ contentTypeString = ContentType.APPLICATION_JSON.toContentTypeString();
+ break;
+ }
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE, contentTypeString);
+ response.setContent(body);
+
+ return response;
+ } catch (IOException e) {
+ // Should not happen
+ // TODO: Check what we can do here.
+ throw new ODataRuntimeException(e);
+ }
+ }
+
+ private List<DebugInfo> createParts(ODataRequest request, ODataResponse applicationResponse, Exception exception,
+ Map<String, String> serverEnvironmentVaribles, List<RuntimeMeasurement> runtimeInformation) {
+ List<DebugInfo> parts = new ArrayList<DebugInfo>();
+
+ // request
+ parts.add(new DebugInfoRequest(request));
+
+ // response
+ // TODO: Check service URI
+ parts.add(new DebugInfoResponse(applicationResponse, request.getRawBaseUri()));
+
+ // server
+ if (serverEnvironmentVaribles != null && !serverEnvironmentVaribles.isEmpty()) {
+ parts.add(new DebugInfoServer(serverEnvironmentVaribles));
+ }
+
+// // URI
+// Throwable candidate = exception;
+// while (candidate != null && !(candidate instanceof ExpressionParserException)) {
+// candidate = candidate.getCause();
+// }
+// final ExpressionParserException expressionParserException = (ExpressionParserException) candidate;
+// if (uriInfo != null
+// && (uriInfo.getFilter() != null || uriInfo.getOrderBy() != null
+// || !uriInfo.getExpand().isEmpty() || !uriInfo.getSelect().isEmpty())
+// || expressionParserException != null && expressionParserException.getFilterTree() != null) {
+// parts.add(new DebugInfoUri(uriInfo, expressionParserException));
+// }
+//
+// // runtime measurements
+ if (runtimeInformation != null && !runtimeInformation.isEmpty()) {
+ parts.add(new DebugInfoRuntime(runtimeInformation));
+ }
+//
+// // exceptions
+ if (exception != null) {
+ parts.add(new DebugInfoException(exception));
+ }
+
+ return parts;
+ }
+
+ private InputStream wrapInJson(final List<DebugInfo> parts) throws IOException {
+ CircleStreamBuffer csb = new CircleStreamBuffer();
+ JsonGenerator gen = new JsonFactory().createGenerator(csb.getOutputStream(), JsonEncoding.UTF8);
+
+ gen.writeStartObject();
+ DebugInfo requestInfo = parts.get(0);
+ // TODO: Should we really translate to lower case here?
+ gen.writeFieldName(requestInfo.getName().toLowerCase(Locale.ROOT));
+ requestInfo.appendJson(gen);
+
+ DebugInfo responseInfo = parts.get(1);
+ gen.writeFieldName(responseInfo.getName().toLowerCase(Locale.ROOT));
+ responseInfo.appendJson(gen);
+
+ gen.writeFieldName("server");
+ gen.writeStartObject();
+ String version = DebugResponseHelperImpl.class.getPackage().getImplementationVersion();
+ if (version != null) {
+ gen.writeStringField("version", version);
+ } else {
+ gen.writeNullField("version");
+ }
+ for (DebugInfo part : parts.subList(2, parts.size())) {
+ gen.writeFieldName(part.getName().toLowerCase(Locale.ROOT));
+ part.appendJson(gen);
+ }
+ gen.writeEndObject();
+
+ gen.writeEndObject();
+ gen.close();
+
+ return csb.getInputStream();
+ }
+
+ private InputStream wrapInHtml(final List<DebugInfo> parts) throws IOException {
+ StringWriter writer = new StringWriter();
+// PathInfo pathInfo = null;
+// try {
+// pathInfo = context.getPathInfo();
+// } catch (final ODataException e) {}
+//
+// writer.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\n")
+// .append(" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n")
+// .append("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n")
+// .append("<head>\n")
+// .append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n")
+// .append("<title>")
+// .append(pathInfo == null ? "" :
+// escapeHtml(pathInfo.getServiceRoot().relativize(pathInfo.getRequestUri()).getPath()))
+// .append("</title>\n")
+// .append("<style type=\"text/css\">\n")
+// .append("body { font-family: Arial, sans-serif; font-size: 13px;\n")
+// .append(" line-height: 16px; margin: 0;\n")
+// .append(" background-color: #eeeeee; color: #333333; }\n")
+// .append(".header { float: left; }\n")
+// .append(".header a { line-height: 22px; padding: 10px 18px;\n")
+// .append(" text-decoration: none; color: #333333; }\n")
+// .append(":target, .header:nth-last-child(2) { background-color: #cccccc; }\n")
+// .append(":target ~ .header:nth-last-child(2) { background-color: inherit; }\n")
+// .append(".header:focus, .header:hover,\n")
+// .append(" .header:nth-last-child(2):focus, .header:nth-last-child(2):hover\n")
+// .append(" { background-color: #999999; }\n")
+// .append(".section { position: absolute; top: 42px; min-width: 100%;\n")
+// .append(" padding-top: 18px; border-top: 1px solid #dddddd; }\n")
+// .append(".section > * { margin-left: 18px; }\n")
+// .append(":target + .section, .section:last-child { display: block; }\n")
+// .append(".section, :target + .section ~ .section { display: none; }\n")
+// .append("h1 { font-size: 18px; font-weight: normal; margin: 10px 0; }\n")
+// .append("h2 { font-size: 15px; }\n")
+// .append("h2:not(:first-child) { margin-top: 2em; }\n")
+// .append("table { border-collapse: collapse; border-spacing: 0;\n")
+// .append(" margin-top: 1.5em; }\n")
+// .append("table, thead { border-width: 1px 0; border-style: solid;\n")
+// .append(" border-color: #dddddd; text-align: left; }\n")
+// .append("th.name, td.name { padding: 1ex 2em 1ex 0; }\n")
+// .append("tbody > tr:hover { background-color: #cccccc; }\n")
+// .append(".code { font-family: \"Courier New\", monospace; }\n")
+// .append(".code, .tree li { line-height: 15px; }\n")
+// .append(".code a { text-decoration: underline; color: #666666; }\n")
+// .append(".xml .ns { font-style: italic; color: #999999; }\n")
+// .append("ul, .tree { list-style-type: none; }\n")
+// .append("div > ul.expr, div > .expand, .tree { padding-left: 0; }\n")
+// .append(".expr, .expand, .null, .numeric { padding-left: 1.5em; }\n")
+// .append("</style>\n")
+// .append("</head>\n")
+// .append("<body>\n");
+// char count = '0';
+// for (final DebugInfo part : parts) {
+// writer.append("<div class=\"header\" id=\"sec").append(++count).append("\">\n")
+// .append("<h1><a href=\"#sec").append(count).append("\">")
+// .append(part.getName())
+// .append("</a></h1>\n")
+// .append("</div>\n")
+// .append("<div class=\"section\">\n");
+// part.appendHtml(writer);
+// writer.append("</div>\n");
+// }
+// writer.append("</body>\n")
+// .append("</html>\n")
+// .close();
+ byte[] bytes = writer.toString().getBytes("UTF-8");
+ return new ByteArrayInputStream(bytes);
+ }
+
+ protected static String escapeHtml(final String value) {
+ return value == null ? null : value.replace("&", "&").replace("<", "<").replace(">", ">");
+ }
+
+ protected static void appendJsonTable(final JsonGenerator gen, final Map<String, String> entries)
+ throws IOException {
+ gen.writeStartObject();
+
+ for (Map.Entry<String, String> entry : entries.entrySet()) {
+ if (entry.getValue() != null) {
+ gen.writeStringField(entry.getKey(), entry.getValue());
+ } else {
+ gen.writeNullField(entry.getKey());
+ }
+ }
+ gen.writeEndObject();
}
+//
+// protected static void appendHtmlTable(final Writer writer, final Map<String, String> entries) throws IOException {
+// writer.append("<table>\n<thead>\n")
+// .append("<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n")
+// .append("</thead>\n<tbody>\n");
+// for (final String name : entries.keySet()) {
+// final String value = entries.get(name);
+// if (value != null) {
+// writer.append("<tr><td class=\"name\">").append(name).append("</td>")
+// .append("<td class=\"value\">")
+// .append(ODataDebugResponseWrapper.escapeHtml(value))
+// .append("</td></tr>\n");
+// }
+// }
+// writer.append("</tbody>\n</table>\n");
+// }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-tecsvc/pom.xml
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/pom.xml b/lib/server-tecsvc/pom.xml
index 3903811..5bb18ce 100644
--- a/lib/server-tecsvc/pom.xml
+++ b/lib/server-tecsvc/pom.xml
@@ -160,7 +160,6 @@
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
- <scope>test</scope>
</dependency>
</dependencies>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/fb65199d/lib/server-test/pom.xml
----------------------------------------------------------------------
diff --git a/lib/server-test/pom.xml b/lib/server-test/pom.xml
index d715698..f698028 100644
--- a/lib/server-test/pom.xml
+++ b/lib/server-test/pom.xml
@@ -66,7 +66,6 @@
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
- <scope>test</scope>
</dependency>
</dependencies>
[12/18] olingo-odata4 git commit: [OLINGO-659] Minor code refactoring
Posted by ch...@apache.org.
[OLINGO-659] Minor code refactoring
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/305f54dc
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/305f54dc
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/305f54dc
Branch: refs/heads/OLINGO-640
Commit: 305f54dcf27dabca5fdeefe01fb4cc9e7fd67d56
Parents: 57a11af
Author: Michael Bolz <mi...@sap.com>
Authored: Tue Jul 28 20:25:52 2015 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Wed Jul 29 20:40:30 2015 +0200
----------------------------------------------------------------------
.../json/ODataJsonDeserializer.java | 275 +++++++++++--------
.../json/ODataJsonDeserializerEntityTest.java | 50 ++++
2 files changed, 203 insertions(+), 122 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/305f54dc/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
index 84beb61..9c6798d 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
@@ -63,7 +63,6 @@ import org.apache.olingo.server.core.deserializer.helper.ExpandTreeBuilderImpl;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
@@ -202,9 +201,8 @@ public class ODataJsonDeserializer implements ODataDeserializer {
throws DeserializerException {
try {
ObjectNode tree = parseJsonTree(stream);
- Map<String, Parameter> parameters = new LinkedHashMap<String, Parameter>();
if (tree != null) {
- consumeParameters(edmAction, tree, parameters);
+ Map<String, Parameter> parameters = consumeParameters(edmAction, tree);
final List<String> toRemove = new ArrayList<String>();
Iterator<Entry<String, JsonNode>> fieldsIterator = tree.fields();
@@ -222,8 +220,9 @@ public class ODataJsonDeserializer implements ODataDeserializer {
// remove here to avoid iterator issues.
tree.remove(toRemove);
assertJsonNodeIsEmpty(tree);
- }
return DeserializerResultImpl.with().actionParameters(parameters).build();
+ }
+ return DeserializerResultImpl.with().build();
} catch (final JsonParseException e) {
throw new DeserializerException("An JsonParseException occurred", e,
@@ -237,58 +236,35 @@ public class ODataJsonDeserializer implements ODataDeserializer {
}
}
- private ObjectNode parseJsonTree(final InputStream stream)
- throws IOException, JsonParseException, JsonProcessingException {
+ private ObjectNode parseJsonTree(final InputStream stream) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY, true);
JsonParser parser = new JsonFactory(objectMapper).createParser(stream);
- ObjectNode tree = parser.getCodec().readTree(parser);
- return tree;
+ return parser.getCodec().readTree(parser);
}
- private void consumeParameters(final EdmAction edmAction, final ObjectNode node,
- final Map<String, Parameter> parameters)
+ private Map<String, Parameter> consumeParameters(final EdmAction edmAction, final ObjectNode node)
throws DeserializerException {
List<String> parameterNames = edmAction.getParameterNames();
if (edmAction.isBound()) {
// The binding parameter must not occur in the payload.
parameterNames = parameterNames.subList(1, parameterNames.size());
}
+ Map<String, Parameter> parameters = new LinkedHashMap<String, Parameter>();
for (final String paramName : parameterNames) {
final EdmParameter edmParameter = edmAction.getParameter(paramName);
- Parameter parameter = new Parameter();
- parameter.setName(paramName);
- JsonNode jsonNode = node.get(paramName);
switch (edmParameter.getType().getKind()) {
case PRIMITIVE:
case DEFINITION:
case ENUM:
- if (jsonNode == null || jsonNode.isNull()) {
- if (!edmParameter.isNullable()) {
- throw new DeserializerException("Non-nullable parameter not present or null",
- DeserializerException.MessageKeys.INVALID_NULL_PARAMETER, paramName);
- }
- if (edmParameter.isCollection()) {
- throw new DeserializerException("Collection must not be null for parameter: " + paramName,
- DeserializerException.MessageKeys.INVALID_NULL_PARAMETER, paramName);
- }
- parameter.setValue(ValueType.PRIMITIVE, null);
- parameters.put(paramName, parameter);
- node.remove(paramName);
- } else {
- Property consumePropertyNode =
- consumePropertyNode(edmParameter.getName(), edmParameter.getType(), edmParameter.isCollection(),
- edmParameter.isNullable(), edmParameter.getMaxLength(), edmParameter.getPrecision(), edmParameter
- .getScale(), true, edmParameter.getMapping(), jsonNode);
- parameter.setValue(consumePropertyNode.getValueType(), consumePropertyNode.getValue());
- parameters.put(paramName, parameter);
- node.remove(paramName);
- }
+ Parameter parameter = createParameter(node.get(paramName), paramName, edmParameter);
+ parameters.put(paramName, parameter);
+ node.remove(paramName);
break;
case COMPLEX:
case ENTITY:
- throw new DeserializerException("Entity an complex parameters currently not Implemented",
+ throw new DeserializerException("Entity and complex parameters currently not Implemented",
DeserializerException.MessageKeys.NOT_IMPLEMENTED);
default:
throw new DeserializerException("Invalid type kind " + edmParameter.getType().getKind().toString()
@@ -296,6 +272,31 @@ public class ODataJsonDeserializer implements ODataDeserializer {
paramName);
}
}
+ return parameters;
+ }
+
+ private Parameter createParameter(JsonNode node, String paramName, EdmParameter edmParameter) throws
+ DeserializerException {
+ Parameter parameter = new Parameter();
+ parameter.setName(paramName);
+ if (node == null || node.isNull()) {
+ if (!edmParameter.isNullable()) {
+ throw new DeserializerException("Non-nullable parameter not present or null",
+ MessageKeys.INVALID_NULL_PARAMETER, paramName);
+ }
+ if (edmParameter.isCollection()) {
+ throw new DeserializerException("Collection must not be null for parameter: " + paramName,
+ MessageKeys.INVALID_NULL_PARAMETER, paramName);
+ }
+ parameter.setValue(ValueType.PRIMITIVE, null);
+ } else {
+ Property consumePropertyNode =
+ consumePropertyNode(edmParameter.getName(), edmParameter.getType(), edmParameter.isCollection(),
+ edmParameter.isNullable(), edmParameter.getMaxLength(), edmParameter.getPrecision(), edmParameter
+ .getScale(), true, edmParameter.getMapping(), node);
+ parameter.setValue(consumePropertyNode.getValueType(), consumePropertyNode.getValue());
+ }
+ return parameter;
}
/**
@@ -342,9 +343,8 @@ public class ODataJsonDeserializer implements ODataDeserializer {
DeserializerException.MessageKeys.INVALID_NULL_PROPERTY, propertyName);
}
Property property = consumePropertyNode(edmProperty.getName(), edmProperty.getType(),
- edmProperty.isCollection(),
- edmProperty.isNullable(), edmProperty.getMaxLength(), edmProperty.getPrecision(), edmProperty.getScale(),
- edmProperty.isUnicode(), edmProperty.getMapping(),
+ edmProperty.isCollection(), edmProperty.isNullable(), edmProperty.getMaxLength(),
+ edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(), edmProperty.getMapping(),
jsonNode);
entity.addProperty(property);
node.remove(propertyName);
@@ -360,41 +360,59 @@ public class ODataJsonDeserializer implements ODataDeserializer {
JsonNode jsonNode = node.get(navigationPropertyName);
if (jsonNode != null) {
EdmNavigationProperty edmNavigationProperty = edmEntityType.getNavigationProperty(navigationPropertyName);
- boolean isNullable = edmNavigationProperty.isNullable();
- if ((jsonNode.isNull() && !isNullable) || (jsonNode.isNull() && edmNavigationProperty.isCollection())) {
- throw new DeserializerException("Property: " + navigationPropertyName + " must not be null.",
- DeserializerException.MessageKeys.INVALID_NULL_PROPERTY, navigationPropertyName);
- }
+ checkNotNullOrValidNull(jsonNode, edmNavigationProperty);
- Link link = new Link();
- link.setTitle(navigationPropertyName);
- final ExpandTreeBuilder childExpandBuilder = (expandBuilder != null) ?
- expandBuilder.expand(edmNavigationProperty) : null;
- if (jsonNode.isArray() && edmNavigationProperty.isCollection()) {
- link.setType(Constants.ENTITY_SET_NAVIGATION_LINK_TYPE);
- EntityCollection inlineEntitySet = new EntityCollection();
- inlineEntitySet.getEntities().addAll(consumeEntitySetArray(edmNavigationProperty.getType(), jsonNode,
- childExpandBuilder));
- link.setInlineEntitySet(inlineEntitySet);
- } else if (!jsonNode.isArray() && (!jsonNode.isValueNode() || jsonNode.isNull())
- && !edmNavigationProperty.isCollection()) {
- link.setType(Constants.ENTITY_NAVIGATION_LINK_TYPE);
- if (!jsonNode.isNull()) {
- Entity inlineEntity = consumeEntityNode(edmNavigationProperty.getType(), (ObjectNode) jsonNode,
- childExpandBuilder);
- link.setInlineEntity(inlineEntity);
- }
- } else {
- throw new DeserializerException("Invalid value: " + jsonNode.getNodeType()
- + " for expanded navigation property: " + navigationPropertyName,
- DeserializerException.MessageKeys.INVALID_VALUE_FOR_NAVIGATION_PROPERTY, navigationPropertyName);
- }
+ Link link = createLink(expandBuilder, navigationPropertyName, jsonNode, edmNavigationProperty);
entity.getNavigationLinks().add(link);
node.remove(navigationPropertyName);
}
}
}
+ /**
+ * Check if jsonNode is not null or if null but nullable or collection navigationProperty
+ *
+ * @param jsonNode related json node
+ * @param edmNavigationProperty related navigation property
+ * @throws DeserializerException if jsonNode is not null or if null but nullable or collection navigationProperty
+ */
+ private void checkNotNullOrValidNull(JsonNode jsonNode,
+ EdmNavigationProperty edmNavigationProperty) throws DeserializerException {
+ boolean isNullable = edmNavigationProperty.isNullable();
+ if ((jsonNode.isNull() && !isNullable) || (jsonNode.isNull() && edmNavigationProperty.isCollection())) {
+ throw new DeserializerException("Property: " + edmNavigationProperty.getName() + " must not be null.",
+ MessageKeys.INVALID_NULL_PROPERTY, edmNavigationProperty.getName());
+ }
+ }
+
+ private Link createLink(ExpandTreeBuilder expandBuilder, String navigationPropertyName, JsonNode jsonNode,
+ EdmNavigationProperty edmNavigationProperty) throws DeserializerException {
+ Link link = new Link();
+ link.setTitle(navigationPropertyName);
+ final ExpandTreeBuilder childExpandBuilder = (expandBuilder != null) ?
+ expandBuilder.expand(edmNavigationProperty) : null;
+ if (jsonNode.isArray() && edmNavigationProperty.isCollection()) {
+ link.setType(Constants.ENTITY_SET_NAVIGATION_LINK_TYPE);
+ EntityCollection inlineEntitySet = new EntityCollection();
+ inlineEntitySet.getEntities().addAll(
+ consumeEntitySetArray(edmNavigationProperty.getType(), jsonNode, childExpandBuilder));
+ link.setInlineEntitySet(inlineEntitySet);
+ } else if (!jsonNode.isArray() && (!jsonNode.isValueNode() || jsonNode.isNull())
+ && !edmNavigationProperty.isCollection()) {
+ link.setType(Constants.ENTITY_NAVIGATION_LINK_TYPE);
+ if (!jsonNode.isNull()) {
+ Entity inlineEntity = consumeEntityNode(edmNavigationProperty.getType(), (ObjectNode) jsonNode,
+ childExpandBuilder);
+ link.setInlineEntity(inlineEntity);
+ }
+ } else {
+ throw new DeserializerException("Invalid value: " + jsonNode.getNodeType()
+ + " for expanded navigation property: " + navigationPropertyName,
+ MessageKeys.INVALID_VALUE_FOR_NAVIGATION_PROPERTY, navigationPropertyName);
+ }
+ return link;
+ }
+
private Link consumeBindingLink(final String key, final JsonNode jsonNode, final EdmEntityType edmEntityType)
throws DeserializerException {
String[] splitKey = key.split("@");
@@ -450,11 +468,11 @@ public class ODataJsonDeserializer implements ODataDeserializer {
property.setName(name);
property.setType(type.getFullQualifiedName().getFullQualifiedNameAsString());
if (isCollection) {
- consumePropertyCollectionNode(name, type, isNullable, maxLength, precision, scale, isUnicode, mapping,
- jsonNode, property);
+ consumePropertyCollectionNode(name, type, isNullable, maxLength, precision, scale, isUnicode, mapping, jsonNode,
+ property);
} else {
- consumePropertySingleNode(name, type, isNullable, maxLength, precision, scale, isUnicode, mapping,
- jsonNode, property);
+ consumePropertySingleNode(name, type, isNullable, maxLength, precision, scale, isUnicode, mapping, jsonNode,
+ property);
}
return property;
}
@@ -695,7 +713,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
/**
* This method either returns the primitive types default class or the manually mapped class if present.
- * @param edmMapping
+ * @param mapping
* @param edmPrimitiveType
* @return the java class to be used during deserialization
*/
@@ -736,7 +754,8 @@ public class ODataJsonDeserializer implements ODataDeserializer {
private void checkJsonTypeBasedOnPrimitiveType(final String propertyName, final String edmPrimitiveTypeName,
final JsonNode jsonNode)
- throws DeserializerException {
+ throws DeserializerException {
+
EdmPrimitiveTypeKind primKind;
try {
primKind = EdmPrimitiveTypeKind.valueOf(edmPrimitiveTypeName);
@@ -744,60 +763,72 @@ public class ODataJsonDeserializer implements ODataDeserializer {
throw new DeserializerException("Unknown Primitive Type: " + edmPrimitiveTypeName, e,
DeserializerException.MessageKeys.UNKNOWN_PRIMITIVE_TYPE, edmPrimitiveTypeName, propertyName);
}
- switch (primKind) {
- // Booleans
- case Boolean:
- if (!jsonNode.isBoolean()) {
- throw new DeserializerException("Invalid json type: " + jsonNode.getNodeType() + " for edm " + primKind
- + " property: " + propertyName, DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, propertyName);
+
+ boolean valid = matchTextualCase(jsonNode, primKind);
+ valid |= matchNumberCase(jsonNode, primKind);
+ valid |= matchBooleanCase(jsonNode, primKind);
+ valid |= matchIEEENumberCase(jsonNode, primKind);
+
+ if(!valid) {
+ throw new DeserializerException("Invalid json type: " + jsonNode.getNodeType() + " for edm " + primKind
+ + " property: " + propertyName, DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, propertyName);
+ }
+ }
+
+ private boolean matchIEEENumberCase(JsonNode node, EdmPrimitiveTypeKind primKind) {
+ switch (primKind) {
+ case Int64:
+ case Decimal:
+ // Numbers (either numbers or string)
+ if (isIEEE754Compatible) {
+ return node.isTextual();
+ } else {
+ return node.isNumber();
+ }
}
- break;
- // Numbers (must be numbers)
- case Int16:
- case Int32:
- case Byte:
- case SByte:
- case Single:
- case Double:
- if (!jsonNode.isNumber()) {
- throw new DeserializerException("Invalid json type: " + jsonNode.getNodeType() + " for edm " + primKind
- + " property: " + propertyName, DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, propertyName);
+ return false;
+ }
+
+ private boolean matchBooleanCase(JsonNode node, EdmPrimitiveTypeKind primKind) {
+ if(node.isBoolean()) {
+ switch (primKind) {
+ case Boolean:
+ return true;
}
- break;
- case Int64:
- case Decimal:
- // Numbers (eighter numers or string)
- if (isIEEE754Compatible) {
- if (!jsonNode.isTextual()) {
- throw new DeserializerException("Invalid json type: " + jsonNode.getNodeType() + " for edm " + primKind
- + " property: " + propertyName, DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY,
- propertyName);
- }
- } else {
- if (!jsonNode.isNumber()) {
- throw new DeserializerException("Invalid json type: " + jsonNode.getNodeType() + " for edm " + primKind
- + " property: " + propertyName, DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY,
- propertyName);
- }
+ }
+ return false;
+ }
+
+ private boolean matchNumberCase(JsonNode node, EdmPrimitiveTypeKind primKind) {
+ if(node.isNumber()) {
+ switch (primKind) {
+ // Numbers (must be numbers)
+ case Int16:
+ case Int32:
+ case Byte:
+ case SByte:
+ case Single:
+ case Double:
+ return true;
}
- break;
- // Strings
- case String:
- case Binary:
- case Date:
- case DateTimeOffset:
- case Duration:
- case Guid:
- case TimeOfDay:
- if (!jsonNode.isTextual()) {
- throw new DeserializerException("Invalid json type: " + jsonNode.getNodeType() + " for edm " + primKind
- + " property: " + propertyName, DeserializerException.MessageKeys.INVALID_VALUE_FOR_PROPERTY, propertyName);
+ }
+ return false;
+ }
+
+ private boolean matchTextualCase(JsonNode node, EdmPrimitiveTypeKind primKind) {
+ if(node.isTextual()) {
+ switch (primKind) {
+ case String:
+ case Binary:
+ case Date:
+ case DateTimeOffset:
+ case Duration:
+ case Guid:
+ case TimeOfDay:
+ return true;
}
- break;
- default:
- throw new DeserializerException("Unsupported Edm Primitive Type: " + primKind,
- DeserializerException.MessageKeys.NOT_IMPLEMENTED);
}
+ return false;
}
@Override
@@ -809,7 +840,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
JsonParser parser = new JsonFactory(objectMapper).createParser(stream);
final ObjectNode tree = parser.getCodec().readTree(parser);
- Property property = null;
+ final Property property;
JsonNode jsonNode = tree.get(Constants.VALUE);
if (jsonNode != null) {
property = consumePropertyNode(edmProperty.getName(), edmProperty.getType(),
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/305f54dc/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
index 4a03b03..5388b40 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
@@ -1520,6 +1520,56 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe
deserializer.entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim"))).getEntity();
}
+ @Test(expected = DeserializerException.class)
+ public void ieee754CompatibleAsNumber() throws Exception {
+ ODataDeserializer deserializer = OData.newInstance().createDeserializer(CONTENT_TYPE_JSON_IEEE754Compatible);
+ String entityString =
+ "{\"PropertyInt16\":32767," +
+ "\"PropertyString\":\"First Resource - positive values\"," +
+ "\"PropertyBoolean\":null," +
+ "\"PropertyByte\":255," +
+ "\"PropertySByte\":127," +
+ "\"PropertyInt32\":2147483647," +
+ "\"PropertyInt64\":123," +
+ "\"PropertySingle\":1.79E20," +
+ "\"PropertyDouble\":-1.79E19," +
+ "\"PropertyDecimal\":\"null\"," +
+ "\"PropertyBinary\":\"ASNFZ4mrze8=\"," +
+ "\"PropertyDate\":null," +
+ "\"PropertyDateTimeOffset\":\"2012-12-03T07:16:23Z\"," +
+ "\"PropertyDuration\":\"PT6S\"," +
+ "\"PropertyGuid\":\"01234567-89ab-cdef-0123-456789abcdef\"," +
+ "\"PropertyTimeOfDay\":\"03:26:05\"}";
+
+ final InputStream stream = new ByteArrayInputStream(entityString.getBytes());
+ deserializer.entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim"))).getEntity();
+ }
+
+ @Test(expected = DeserializerException.class)
+ public void ieee754NotCompatibleAsString() throws Exception {
+ ODataDeserializer deserializer = OData.newInstance().createDeserializer(CONTENT_TYPE_JSON);
+ String entityString =
+ "{\"PropertyInt16\":32767," +
+ "\"PropertyString\":\"First Resource - positive values\"," +
+ "\"PropertyBoolean\":null," +
+ "\"PropertyByte\":255," +
+ "\"PropertySByte\":127," +
+ "\"PropertyInt32\":2147483647," +
+ "\"PropertyInt64\":\"123\"," +
+ "\"PropertySingle\":1.79E20," +
+ "\"PropertyDouble\":-1.79E19," +
+ "\"PropertyDecimal\":\"null\"," +
+ "\"PropertyBinary\":\"ASNFZ4mrze8=\"," +
+ "\"PropertyDate\":null," +
+ "\"PropertyDateTimeOffset\":\"2012-12-03T07:16:23Z\"," +
+ "\"PropertyDuration\":\"PT6S\"," +
+ "\"PropertyGuid\":\"01234567-89ab-cdef-0123-456789abcdef\"," +
+ "\"PropertyTimeOfDay\":\"03:26:05\"}";
+
+ final InputStream stream = new ByteArrayInputStream(entityString.getBytes());
+ deserializer.entity(stream, edm.getEntityType(new FullQualifiedName("Namespace1_Alias", "ETAllPrim"))).getEntity();
+ }
+
private void checkPropertyJsonType(final String entityString) throws DeserializerException {
InputStream stream = new ByteArrayInputStream(entityString.getBytes());
ODataDeserializer deserializer = OData.newInstance().createDeserializer(CONTENT_TYPE_JSON);
[08/18] olingo-odata4 git commit: [OLINGO-713] Added tutorial project
for system query options - expand/select
Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/util/Util.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/util/Util.java b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/util/Util.java
deleted file mode 100755
index c21d352..0000000
--- a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/util/Util.java
+++ /dev/null
@@ -1,105 +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 myservice.mynamespace.util;
-
-import java.util.List;
-import java.util.Locale;
-
-import org.apache.olingo.commons.api.data.Entity;
-import org.apache.olingo.commons.api.data.EntityCollection;
-import org.apache.olingo.commons.api.edm.EdmEntitySet;
-import org.apache.olingo.commons.api.edm.EdmEntityType;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
-import org.apache.olingo.commons.api.edm.EdmProperty;
-import org.apache.olingo.commons.api.edm.EdmType;
-import org.apache.olingo.commons.api.http.HttpStatusCode;
-import org.apache.olingo.server.api.ODataApplicationException;
-import org.apache.olingo.server.api.uri.UriInfoResource;
-import org.apache.olingo.server.api.uri.UriParameter;
-import org.apache.olingo.server.api.uri.UriResource;
-import org.apache.olingo.server.api.uri.UriResourceEntitySet;
-
-public class Util {
-
- public static Entity findEntity(EdmEntityType edmEntityType, EntityCollection entitySet,
- List<UriParameter> keyParams) throws ODataApplicationException {
-
- List<Entity> entityList = entitySet.getEntities();
-
- // loop over all entities in order to find that one that matches all keys in request
- // e.g. contacts(ContactID=1, CompanyID=1)
- for (Entity entity: entityList) {
- boolean foundEntity = entityMatchesAllKeys(edmEntityType, entity, keyParams);
- if (foundEntity) {
- return entity;
- }
- }
-
- return null;
- }
-
- public static boolean entityMatchesAllKeys(EdmEntityType edmEntityType, Entity entity, List<UriParameter> keyParams)
- throws ODataApplicationException {
-
- // loop over all keys
- for (final UriParameter key : keyParams) {
- // key
- String keyName = key.getName();
- String keyText = key.getText();
-
- // Edm: we need this info for the comparison below
- EdmProperty edmKeyProperty = (EdmProperty) edmEntityType.getProperty(keyName);
- Boolean isNullable = edmKeyProperty.isNullable();
- Integer maxLength = edmKeyProperty.getMaxLength();
- Integer precision = edmKeyProperty.getPrecision();
- Boolean isUnicode = edmKeyProperty.isUnicode();
- Integer scale = edmKeyProperty.getScale();
- // get the EdmType in order to compare
- EdmType edmType = edmKeyProperty.getType();
- EdmPrimitiveType edmPrimitiveType = (EdmPrimitiveType) edmType;
-
- // Runtime data: the value of the current entity
- // don't need to check for null, this is done in olingo library
- Object valueObject = entity.getProperty(keyName).getValue();
-
- // now need to compare the valueObject with the keyText String
- // this is done using the type.valueToString
- String valueAsString;
- try {
- valueAsString = edmPrimitiveType.valueToString(valueObject, isNullable, maxLength, precision, scale, isUnicode);
- } catch (EdmPrimitiveTypeException e) {
- throw new ODataApplicationException("Failed to retrieve String value", HttpStatusCode.INTERNAL_SERVER_ERROR
- .getStatusCode(), Locale.ENGLISH, e);
- }
-
- if (valueAsString == null) {
- return false;
- }
-
- boolean matches = valueAsString.equals(keyText);
- if (!matches) {
- // if any of the key properties is not found in the entity, we don't need to search further
- return false;
- }
- }
-
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/web/DemoServlet.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/web/DemoServlet.java b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/web/DemoServlet.java
deleted file mode 100755
index fe5cdbb..0000000
--- a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/web/DemoServlet.java
+++ /dev/null
@@ -1,76 +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 myservice.mynamespace.web;
-
-import java.io.IOException;
-import java.lang.Override;import java.lang.RuntimeException;import java.util.ArrayList;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-import myservice.mynamespace.data.Storage;
-import myservice.mynamespace.service.DemoEdmProvider;
-import myservice.mynamespace.service.DemoEntityCollectionProcessor;
-import myservice.mynamespace.service.DemoEntityProcessor;
-import myservice.mynamespace.service.DemoPrimitiveProcessor;
-
-import org.apache.olingo.server.api.OData;
-import org.apache.olingo.server.api.ODataHttpHandler;
-import org.apache.olingo.server.api.ServiceMetadata;
-import org.apache.olingo.server.api.edmx.EdmxReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class DemoServlet extends HttpServlet {
-
- private static final long serialVersionUID = 1L;
- private static final Logger LOG = LoggerFactory.getLogger(DemoServlet.class);
-
-
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- try {
- HttpSession session = req.getSession(true);
- Storage storage = (Storage) session.getAttribute(Storage.class.getName());
- if (storage == null) {
- storage = new Storage();
- session.setAttribute(Storage.class.getName(), storage);
- }
-
- // create odata handler and configure it with EdmProvider and Processor
- OData odata = OData.newInstance();
- ServiceMetadata edm = odata.createServiceMetadata(new DemoEdmProvider(), new ArrayList<EdmxReference>());
- ODataHttpHandler handler = odata.createHandler(edm);
- handler.register(new DemoEntityCollectionProcessor(storage));
- handler.register(new DemoEntityProcessor(storage));
- handler.register(new DemoPrimitiveProcessor(storage));
-
- // let the handler do the work
- handler.process(req, resp);
- } catch (RuntimeException e) {
- LOG.error("Server Error occurred in ExampleServlet", e);
- throw new ServletException(e);
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/webapp/WEB-INF/web.xml b/samples/tutorials/p5_queryoptions/src/main/webapp/WEB-INF/web.xml
deleted file mode 100755
index 21de52a..0000000
--- a/samples/tutorials/p5_queryoptions/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?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.
--->
-<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- id="WebApp_ID" version="2.5">
-
- <!-- Register the HttpServlet implementation -->
- <servlet>
- <servlet-name>DemoServlet</servlet-name>
- <servlet-class>myservice.mynamespace.web.DemoServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
-
- <!--
- Our OData service can be invoked at
- http://localhost:8080/DemoService/DemoService.svc
- -->
- <servlet-mapping>
- <servlet-name>DemoServlet</servlet-name>
- <url-pattern>/DemoService.svc/*</url-pattern>
- </servlet-mapping>
-</web-app>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/webapp/index.jsp b/samples/tutorials/p5_queryoptions/src/main/webapp/index.jsp
deleted file mode 100755
index 7ffb4ba..0000000
--- a/samples/tutorials/p5_queryoptions/src/main/webapp/index.jsp
+++ /dev/null
@@ -1,26 +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.
-
--->
-<html>
-<body>
-<h2>Hello World!</h2>
-<a href="DemoService.svc/">OData Olingo V4 Demo Service</a>
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p6_queryoptions-es/pom.xml
----------------------------------------------------------------------
diff --git a/samples/tutorials/p6_queryoptions-es/pom.xml b/samples/tutorials/p6_queryoptions-es/pom.xml
new file mode 100755
index 0000000..bb095ad
--- /dev/null
+++ b/samples/tutorials/p6_queryoptions-es/pom.xml
@@ -0,0 +1,80 @@
+<?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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>my.group.id</groupId>
+ <artifactId>DemoService-QueryOptions-ES</artifactId>
+ <packaging>war</packaging>
+ <version>0.0.1</version>
+
+ <name>${project.artifactId}-Webapp</name>
+
+ <build>
+ <finalName>DemoService</finalName>
+ </build>
+
+ <properties>
+ <javax.version>2.5</javax.version>
+ <odata.version>4.0.0-beta-03</odata.version>
+ <slf4j.version>1.7.7</slf4j.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>${javax.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>odata-server-api</artifactId>
+ <version>${odata.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>odata-server-core</artifactId>
+ <version>${odata.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>odata-commons-api</artifactId>
+ <version>${odata.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>odata-commons-core</artifactId>
+ <version>${odata.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>${slf4j.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/data/Storage.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/data/Storage.java b/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/data/Storage.java
new file mode 100755
index 0000000..2034fe6
--- /dev/null
+++ b/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/data/Storage.java
@@ -0,0 +1,252 @@
+/*
+ * 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 myservice.mynamespace.data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import myservice.mynamespace.service.DemoEdmProvider;
+import myservice.mynamespace.util.Util;
+
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntityCollection;
+import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.data.ValueType;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.server.api.uri.UriParameter;
+
+public class Storage {
+
+ // represent our database
+ private List<Entity> productList;
+ private List<Entity> categoryList;
+
+ public Storage() {
+
+ productList = new ArrayList<Entity>();
+ categoryList = new ArrayList<Entity>();
+
+ // creating some sample data
+ initProductSampleData();
+ initCategorySampleData();
+ }
+
+ /* PUBLIC FACADE */
+
+ public EntityCollection readEntitySetData(EdmEntitySet edmEntitySet) {
+ EntityCollection entitySet = null;
+
+ if (edmEntitySet.getName().equals(DemoEdmProvider.ES_PRODUCTS_NAME)) {
+ entitySet = getProducts();
+ } else if (edmEntitySet.getName().equals(DemoEdmProvider.ES_CATEGORIES_NAME)) {
+ entitySet = getCategories();
+ }
+
+ return entitySet;
+ }
+
+ public Entity readEntityData(EdmEntitySet edmEntitySet, List<UriParameter> keyParams) {
+ Entity entity = null;
+
+ EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+
+ if (edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)) {
+ entity = getProduct(edmEntityType, keyParams);
+ } else if (edmEntityType.getName().equals(DemoEdmProvider.ET_CATEGORY_NAME)) {
+ entity = getCategory(edmEntityType, keyParams);
+ }
+
+ return entity;
+ }
+
+ // Navigation
+
+ public Entity getRelatedEntity(Entity entity, EdmEntityType relatedEntityType) {
+ EntityCollection collection = getRelatedEntityCollection(entity, relatedEntityType);
+ if (collection.getEntities().isEmpty()) {
+ return null;
+ }
+ return collection.getEntities().get(0);
+ }
+
+ public Entity getRelatedEntity(Entity entity, EdmEntityType relatedEntityType, List<UriParameter> keyPredicates) {
+
+ EntityCollection relatedEntities = getRelatedEntityCollection(entity, relatedEntityType);
+ return Util.findEntity(relatedEntityType, relatedEntities, keyPredicates);
+ }
+
+ public EntityCollection getRelatedEntityCollection(Entity sourceEntity, EdmEntityType targetEntityType) {
+ EntityCollection navigationTargetEntityCollection = new EntityCollection();
+
+ FullQualifiedName relatedEntityFqn = targetEntityType.getFullQualifiedName();
+ String sourceEntityFqn = sourceEntity.getType();
+
+ if (sourceEntityFqn.equals(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString())
+ && relatedEntityFqn.equals(DemoEdmProvider.ET_CATEGORY_FQN)) {
+ // relation Products->Category (result all categories)
+ int productID = (Integer) sourceEntity.getProperty("ID").getValue();
+ if (productID == 1 || productID == 2) {
+ navigationTargetEntityCollection.getEntities().add(categoryList.get(0));
+ } else if (productID == 3 || productID == 4) {
+ navigationTargetEntityCollection.getEntities().add(categoryList.get(1));
+ } else if (productID == 5 || productID == 6) {
+ navigationTargetEntityCollection.getEntities().add(categoryList.get(2));
+ }
+ } else if (sourceEntityFqn.equals(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString())
+ && relatedEntityFqn.equals(DemoEdmProvider.ET_PRODUCT_FQN)) {
+ // relation Category->Products (result all products)
+ int categoryID = (Integer) sourceEntity.getProperty("ID").getValue();
+ if (categoryID == 1) {
+ // the first 2 products are notebooks
+ navigationTargetEntityCollection.getEntities().addAll(productList.subList(0, 2));
+ } else if (categoryID == 2) {
+ // the next 2 products are organizers
+ navigationTargetEntityCollection.getEntities().addAll(productList.subList(2, 4));
+ } else if (categoryID == 3) {
+ // the first 2 products are monitors
+ navigationTargetEntityCollection.getEntities().addAll(productList.subList(4, 6));
+ }
+ }
+
+ if (navigationTargetEntityCollection.getEntities().isEmpty()) {
+ return null;
+ }
+
+ return navigationTargetEntityCollection;
+ }
+
+ /* INTERNAL */
+
+ private EntityCollection getProducts() {
+ EntityCollection retEntitySet = new EntityCollection();
+
+ for (Entity productEntity : this.productList) {
+ retEntitySet.getEntities().add(productEntity);
+ }
+
+ return retEntitySet;
+ }
+
+ private Entity getProduct(EdmEntityType edmEntityType, List<UriParameter> keyParams) {
+
+ // the list of entities at runtime
+ EntityCollection entityCollection = getProducts();
+
+ /* generic approach to find the requested entity */
+ return Util.findEntity(edmEntityType, entityCollection, keyParams);
+ }
+
+ private EntityCollection getCategories() {
+ EntityCollection entitySet = new EntityCollection();
+
+ for (Entity categoryEntity : this.categoryList) {
+ entitySet.getEntities().add(categoryEntity);
+ }
+
+ return entitySet;
+ }
+
+ private Entity getCategory(EdmEntityType edmEntityType, List<UriParameter> keyParams) {
+
+ // the list of entities at runtime
+ EntityCollection entitySet = getCategories();
+
+ /* generic approach to find the requested entity */
+ return Util.findEntity(edmEntityType, entitySet, keyParams);
+ }
+
+ /* HELPER */
+
+ private void initProductSampleData() {
+
+ Entity entity = new Entity();
+
+ entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1));
+ entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Basic 15"));
+ entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
+ "Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 40GB"));
+ entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
+ productList.add(entity);
+
+ entity = new Entity();
+ entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2));
+ entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Professional 17"));
+ entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
+ "Notebook Professional, 2.8GHz - 15 XGA - 8GB DDR3 RAM - 500GB"));
+ entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
+ productList.add(entity);
+
+ entity = new Entity();
+ entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3));
+ entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "1UMTS PDA"));
+ entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
+ "Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network"));
+ entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
+ productList.add(entity);
+
+ entity = new Entity();
+ entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 4));
+ entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Comfort Easy"));
+ entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
+ "32 GB Digital Assitant with high-resolution color screen"));
+ entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
+ productList.add(entity);
+
+ entity = new Entity();
+ entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 5));
+ entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Ergo Screen"));
+ entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
+ "19 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960"));
+ entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
+ productList.add(entity);
+
+ entity = new Entity();
+ entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 6));
+ entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Flat Basic"));
+ entity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
+ "Optimum Hi-Resolution max. 1600 x 1200 @ 85Hz, Dot Pitch: 0.24mm"));
+ entity.setType(DemoEdmProvider.ET_PRODUCT_FQN.getFullQualifiedNameAsString());
+ productList.add(entity);
+ }
+
+ private void initCategorySampleData() {
+
+ Entity entity = new Entity();
+
+ entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1));
+ entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebooks"));
+ entity.setType(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString());
+ categoryList.add(entity);
+
+ entity = new Entity();
+ entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2));
+ entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Organizers"));
+ entity.setType(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString());
+ categoryList.add(entity);
+
+ entity = new Entity();
+ entity.addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3));
+ entity.addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Monitors"));
+ entity.setType(DemoEdmProvider.ET_CATEGORY_FQN.getFullQualifiedNameAsString());
+ categoryList.add(entity);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java b/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
new file mode 100755
index 0000000..7b1fef8
--- /dev/null
+++ b/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
@@ -0,0 +1,211 @@
+/*
+ * 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 myservice.mynamespace.service;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.olingo.commons.api.ODataException;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
+import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
+import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo;
+import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet;
+import org.apache.olingo.commons.api.edm.provider.CsdlEntityType;
+import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty;
+import org.apache.olingo.commons.api.edm.provider.CsdlNavigationPropertyBinding;
+import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
+import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef;
+import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
+
+public class DemoEdmProvider extends CsdlAbstractEdmProvider {
+
+ // Service Namespace
+ public static final String NAMESPACE = "OData.Demo";
+
+ // EDM Container
+ public static final String CONTAINER_NAME = "Container";
+ public static final FullQualifiedName CONTAINER = new FullQualifiedName(NAMESPACE, CONTAINER_NAME);
+
+ // Entity Types Names
+ public static final String ET_PRODUCT_NAME = "Product";
+ public static final FullQualifiedName ET_PRODUCT_FQN = new FullQualifiedName(NAMESPACE, ET_PRODUCT_NAME);
+
+ public static final String ET_CATEGORY_NAME = "Category";
+ public static final FullQualifiedName ET_CATEGORY_FQN = new FullQualifiedName(NAMESPACE, ET_CATEGORY_NAME);
+
+ // Entity Set Names
+ public static final String ES_PRODUCTS_NAME = "Products";
+ public static final String ES_CATEGORIES_NAME = "Categories";
+
+ @Override
+ public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODataException {
+
+ // this method is called for each EntityType that are configured in the Schema
+ CsdlEntityType entityType = null;
+
+ if (entityTypeName.equals(ET_PRODUCT_FQN)) {
+ // create EntityType properties
+ CsdlProperty id = new CsdlProperty().setName("ID")
+ .setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
+ CsdlProperty name = new CsdlProperty().setName("Name")
+ .setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
+ CsdlProperty description = new CsdlProperty().setName("Description")
+ .setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
+
+ // create PropertyRef for Key element
+ CsdlPropertyRef propertyRef = new CsdlPropertyRef();
+ propertyRef.setName("ID");
+
+ // navigation property: many-to-one, null not allowed (product must have a category)
+ CsdlNavigationProperty navProp = new CsdlNavigationProperty().setName("Category")
+ .setType(ET_CATEGORY_FQN).setNullable(false).setPartner("Products");
+ List<CsdlNavigationProperty> navPropList = new ArrayList<CsdlNavigationProperty>();
+ navPropList.add(navProp);
+
+ // configure EntityType
+ entityType = new CsdlEntityType();
+ entityType.setName(ET_PRODUCT_NAME);
+ entityType.setProperties(Arrays.asList(id, name, description));
+ entityType.setKey(Arrays.asList(propertyRef));
+ entityType.setNavigationProperties(navPropList);
+
+ } else if (entityTypeName.equals(ET_CATEGORY_FQN)) {
+ // create EntityType properties
+ CsdlProperty id = new CsdlProperty().setName("ID")
+ .setType(EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
+ CsdlProperty name = new CsdlProperty().setName("Name")
+ .setType(EdmPrimitiveTypeKind.String.getFullQualifiedName());
+
+ // create PropertyRef for Key element
+ CsdlPropertyRef propertyRef = new CsdlPropertyRef();
+ propertyRef.setName("ID");
+
+ // navigation property: one-to-many
+ CsdlNavigationProperty navProp = new CsdlNavigationProperty().setName("Products")
+ .setType(ET_PRODUCT_FQN).setCollection(true).setPartner("Category");
+ List<CsdlNavigationProperty> navPropList = new ArrayList<CsdlNavigationProperty>();
+ navPropList.add(navProp);
+
+ // configure EntityType
+ entityType = new CsdlEntityType();
+ entityType.setName(ET_CATEGORY_NAME);
+ entityType.setProperties(Arrays.asList(id, name));
+ entityType.setKey(Arrays.asList(propertyRef));
+ entityType.setNavigationProperties(navPropList);
+ }
+
+ return entityType;
+
+ }
+
+ @Override
+ public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) throws ODataException {
+
+ CsdlEntitySet entitySet = null;
+
+ if (entityContainer.equals(CONTAINER)) {
+
+ if (entitySetName.equals(ES_PRODUCTS_NAME)) {
+
+ entitySet = new CsdlEntitySet();
+ entitySet.setName(ES_PRODUCTS_NAME);
+ entitySet.setType(ET_PRODUCT_FQN);
+
+ // navigation
+ CsdlNavigationPropertyBinding navPropBinding = new CsdlNavigationPropertyBinding();
+ navPropBinding.setTarget("Categories"); // the target entity set, where the navigation property points to
+ navPropBinding.setPath("Category"); // the path from entity type to navigation property
+ List<CsdlNavigationPropertyBinding> navPropBindingList = new ArrayList<CsdlNavigationPropertyBinding>();
+ navPropBindingList.add(navPropBinding);
+ entitySet.setNavigationPropertyBindings(navPropBindingList);
+
+ } else if (entitySetName.equals(ES_CATEGORIES_NAME)) {
+
+ entitySet = new CsdlEntitySet();
+ entitySet.setName(ES_CATEGORIES_NAME);
+ entitySet.setType(ET_CATEGORY_FQN);
+
+ // navigation
+ CsdlNavigationPropertyBinding navPropBinding = new CsdlNavigationPropertyBinding();
+ navPropBinding.setTarget("Products"); // the target entity set, where the navigation property points to
+ navPropBinding.setPath("Products"); // the path from entity type to navigation property
+ List<CsdlNavigationPropertyBinding> navPropBindingList = new ArrayList<CsdlNavigationPropertyBinding>();
+ navPropBindingList.add(navPropBinding);
+ entitySet.setNavigationPropertyBindings(navPropBindingList);
+ }
+ }
+
+ return entitySet;
+ }
+
+ @Override
+ public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) throws ODataException {
+
+ // This method is invoked when displaying the service document at
+ // e.g. http://localhost:8080/DemoService/DemoService.svc
+ if (entityContainerName == null || entityContainerName.equals(CONTAINER)) {
+ CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo();
+ entityContainerInfo.setContainerName(CONTAINER);
+ return entityContainerInfo;
+ }
+
+ return null;
+ }
+
+ @Override
+ public List<CsdlSchema> getSchemas() throws ODataException {
+ // create Schema
+ CsdlSchema schema = new CsdlSchema();
+ schema.setNamespace(NAMESPACE);
+
+ // add EntityTypes
+ List<CsdlEntityType> entityTypes = new ArrayList<CsdlEntityType>();
+ entityTypes.add(getEntityType(ET_PRODUCT_FQN));
+ entityTypes.add(getEntityType(ET_CATEGORY_FQN));
+ schema.setEntityTypes(entityTypes);
+
+ // add EntityContainer
+ schema.setEntityContainer(getEntityContainer());
+
+ // finally
+ List<CsdlSchema> schemas = new ArrayList<CsdlSchema>();
+ schemas.add(schema);
+
+ return schemas;
+ }
+
+ @Override
+ public CsdlEntityContainer getEntityContainer() throws ODataException {
+
+ // create EntitySets
+ List<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();
+ entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME));
+ entitySets.add(getEntitySet(CONTAINER, ES_CATEGORIES_NAME));
+
+ // create EntityContainer
+ CsdlEntityContainer entityContainer = new CsdlEntityContainer();
+ entityContainer.setName(CONTAINER_NAME);
+ entityContainer.setEntitySets(entitySets);
+
+ return entityContainer;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java b/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java
new file mode 100755
index 0000000..60f8cd2
--- /dev/null
+++ b/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java
@@ -0,0 +1,160 @@
+/*
+ * 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 myservice.mynamespace.service;
+
+import java.util.List;
+
+import myservice.mynamespace.data.Storage;
+
+import org.apache.olingo.commons.api.Constants;
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntityCollection;
+import org.apache.olingo.commons.api.data.Link;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
+import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.serializer.SerializerResult;
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+import org.apache.olingo.server.api.uri.UriResourceNavigation;
+import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
+import org.apache.olingo.server.api.uri.queryoption.SelectOption;
+
+public class DemoEntityCollectionProcessor implements EntityCollectionProcessor {
+
+ private OData odata;
+ private ServiceMetadata srvMetadata;
+ // our database-mock
+ private Storage storage;
+
+ public DemoEntityCollectionProcessor(Storage storage) {
+ this.storage = storage;
+ }
+
+ public void init(OData odata, ServiceMetadata serviceMetadata) {
+ this.odata = odata;
+ this.srvMetadata = serviceMetadata;
+ }
+
+ /*
+ * This method is invoked when a collection of entities has to be read. In
+ * our example, this can be either a "normal" read operation, or a
+ * navigation:
+ *
+ * Example for "normal" read entity set operation:
+ * http://localhost:8080/DemoService/DemoService.svc/Categories
+ *
+ * Example for navigation
+ * http://localhost:8080/DemoService/DemoService.svc/Categories(3)/Products
+ */
+ public void readEntityCollection(ODataRequest request,
+ ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
+ throws ODataApplicationException, SerializerException {
+
+ // 1st retrieve the requested EdmEntitySet from the uriInfo
+ List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+ // in our example, the first segment is the EntitySet
+ UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
+ EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
+
+ // 2nd: fetch the data from backend for this requested EntitySetName
+ EntityCollection entityCollection = storage.readEntitySetData(edmEntitySet);
+
+ // 3rd: apply system query options
+ SelectOption selectOption = uriInfo.getSelectOption();
+ ExpandOption expandOption = uriInfo.getExpandOption();
+
+ // handle $expand
+ // in our example: http://localhost:8080/DemoService/DemoService.svc/Categories/$expand=Products
+ // or http://localhost:8080/DemoService/DemoService.svc/Products?$expand=Category
+ if (expandOption != null) {
+
+ // retrieve the EdmNavigationProperty from the expand expression
+ // Note: in our example, we have only one NavigationProperty, so we can directly access it
+ ExpandItem expandItem = expandOption.getExpandItems().get(0);
+ // can be 'Category' or 'Products'
+ UriResource uriResource = expandItem.getResourcePath().getUriResourceParts().get(0);
+ // we don't need to handle error cases, as it is done in the Olingo library
+ if (uriResource instanceof UriResourceNavigation) {
+ EdmNavigationProperty edmNavigationProperty = ((UriResourceNavigation) uriResource).getProperty();
+ String navPropName = edmNavigationProperty.getName();
+ EdmEntityType expandEdmEntityType = edmNavigationProperty.getType();
+
+ List<Entity> entityList = entityCollection.getEntities();
+ for (Entity entity : entityList) {
+ Link link = new Link();
+ link.setTitle(navPropName);
+ link.setType(Constants.ENTITY_NAVIGATION_LINK_TYPE);
+
+ if (edmNavigationProperty.isCollection()) { // in case of Categories/$expand=Products
+ // fetch the data for the $expand (to-many navigation) from backend
+ EntityCollection expandEntityCollection = storage.getRelatedEntityCollection(entity, expandEdmEntityType);
+ link.setInlineEntitySet(expandEntityCollection);
+ } else { // in case of Products?$expand=Category
+ // fetch the data for the $expand (to-one navigation) from backend
+ // here we get the data for the expand
+ Entity expandEntity = storage.getRelatedEntity(entity, expandEdmEntityType);
+ link.setInlineEntity(expandEntity);
+ }
+
+ // set the link - containing the expanded data - to the current entity
+ entity.getNavigationLinks().add(link);
+ }
+ }
+ }
+
+ // 4th: serialize
+ EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+ // we need the property names of the $select, in order to build the context URL
+ String selectList = odata.createUriHelper().buildContextURLSelectList(edmEntityType, expandOption, selectOption);
+ ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).selectList(selectList).build();
+
+ // adding the selectOption to the serializerOpts will actually tell the lib to do the job
+ EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with()
+ .contextURL(contextUrl)
+ .select(selectOption)
+ .expand(expandOption)
+ .build();
+
+ ODataSerializer serializer = odata.createSerializer(ODataFormat.fromContentType(responseFormat));
+ SerializerResult serializerResult = serializer.entityCollection(srvMetadata, edmEntityType, entityCollection, opts);
+
+ // 5th: configure the response object: set the body, headers and status code
+ response.setContent(serializerResult.getContent());
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java b/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java
new file mode 100755
index 0000000..f9bcb2b
--- /dev/null
+++ b/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java
@@ -0,0 +1,235 @@
+/*
+ * 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 myservice.mynamespace.service;
+
+import java.util.List;
+import java.util.Locale;
+
+import myservice.mynamespace.data.Storage;
+
+import org.apache.olingo.commons.api.Constants;
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.ContextURL.Suffix;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntityCollection;
+import org.apache.olingo.commons.api.data.Link;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.deserializer.DeserializerException;
+import org.apache.olingo.server.api.processor.EntityProcessor;
+import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.serializer.SerializerResult;
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.uri.UriParameter;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+import org.apache.olingo.server.api.uri.UriResourceNavigation;
+import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
+import org.apache.olingo.server.api.uri.queryoption.SelectOption;
+
+public class DemoEntityProcessor implements EntityProcessor {
+
+ private OData odata;
+ private ServiceMetadata srvMetadata;
+ private Storage storage;
+
+ public DemoEntityProcessor(Storage storage) {
+ this.storage = storage;
+ }
+
+ public void init(OData odata, ServiceMetadata serviceMetadata) {
+ this.odata = odata;
+ this.srvMetadata = serviceMetadata;
+ }
+
+
+// /**
+// * DUMMY example implementation
+// * */
+// public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
+// throws ODataApplicationException, SerializerException {
+//
+// // 1. Analyze the URI
+// EdmEntitySet edmEntitySet = ((UriResourceEntitySet)uriInfo.getUriResourceParts().get(0)).getEntitySet();
+// // get the system query option $expand
+// ExpandOption expandOption = uriInfo.getExpandOption();
+//
+// // 2. get the data.
+//
+// // Note: this is FAKE implementation
+// // used for following request:
+// // http://localhost:8080/DemoService/DemoService.svc/Products(1)?$expand=Category
+//
+// // create hard-coded product entity and set a hard-coded category as inlineEntity for the expand
+// Entity fakeProductEntity = new Entity().addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 11))
+// .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Gamer Mouse"));
+// fakeProductEntity.addProperty(new Property(null, "Description", ValueType.PRIMITIVE, "High end gaming mouse"));
+//
+// // create hard-coded category entity (the target of the $expand)
+// Entity fakeCategoryEntity = new Entity().addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 22))
+// .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Mice"));
+//
+// // create navigation link from product to category
+// Link fakeLink = new Link();
+// fakeLink.setTitle("Category"); // hard-code the name of the navigation property as declared in EdmProvider
+// fakeLink.setInlineEntity(fakeCategoryEntity); // the entity which will be expanded
+//
+// //add the link to the product entity
+// fakeProductEntity.getNavigationLinks().add(fakeLink);
+//
+// // END FAKE
+//
+//
+// // 3. serialize
+// ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).suffix(ContextURL.Suffix.ENTITY).build();
+// // $expand info is added to the serializer options
+// EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).expand(expandOption).build();
+// ODataSerializer serializer = this.odata.createSerializer(ODataFormat.fromContentType(responseFormat));
+// SerializerResult serializerResult = serializer.entity(srvMetadata, edmEntitySet.getEntityType(), fakeProductEntity, options);
+//
+// //4. configure the response object
+// response.setContent(serializerResult.getContent());
+// response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+// response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
+// }
+
+
+
+ public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
+ throws ODataApplicationException, SerializerException {
+
+ // 1. retrieve the Entity Type
+ List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+ // Note: only in our example we can assume that the first segment is the EntitySet
+ UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
+ EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
+
+ // 2. retrieve the data from backend
+ List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
+ Entity entity = storage.readEntityData(edmEntitySet, keyPredicates);
+
+ // 3. apply system query options
+
+ // handle $select
+ SelectOption selectOption = uriInfo.getSelectOption();
+ // in our example, we don't have performance issues, so we can rely upon the handling in the Olingo lib
+ // nothing else to be done
+
+ // handle $expand
+ ExpandOption expandOption = uriInfo.getExpandOption();
+ // in our example: http://localhost:8080/DemoService/DemoService.svc/Categories(1)/$expand=Products
+ // or http://localhost:8080/DemoService/DemoService.svc/Products(1)?$expand=Category
+ if(expandOption != null){
+
+ // retrieve the EdmNavigationProperty from the expand expression
+ // Note: in our example, we have only one NavigationProperty, so we can directly access it
+ ExpandItem expandItem = expandOption.getExpandItems().get(0);
+ // can be 'Category' or 'Products', no path supported
+ UriResource uriResource = expandItem.getResourcePath().getUriResourceParts().get(0);
+ // we don't need to handle error cases, as it is done in the Olingo library
+ if(uriResource instanceof UriResourceNavigation){
+ EdmNavigationProperty edmNavigationProperty = ((UriResourceNavigation)uriResource).getProperty();
+ EdmEntityType expandEdmEntityType = edmNavigationProperty.getType();
+ String navPropName = edmNavigationProperty.getName();
+
+ // build the inline data
+ Link link = new Link();
+ link.setTitle(navPropName);
+ link.setType(Constants.ENTITY_NAVIGATION_LINK_TYPE);
+
+ if(edmNavigationProperty.isCollection()){ // in case of Categories(1)/$expand=Products
+ // fetch the data for the $expand (to-many navigation) from backend
+ // here we get the data for the expand
+ EntityCollection expandEntityCollection = storage.getRelatedEntityCollection(entity, expandEdmEntityType);
+ link.setInlineEntitySet(expandEntityCollection);
+ }else{ // in case of Products(1)?$expand=Category
+ // fetch the data for the $expand (to-one navigation) from backend
+ // here we get the data for the expand
+ Entity expandEntity = storage.getRelatedEntity(entity, expandEdmEntityType);
+ link.setInlineEntity(expandEntity);
+ }
+
+ // set the link - containing the expanded data - to the current entity
+ entity.getNavigationLinks().add(link);
+ }
+ }
+
+
+
+ // 4. serialize
+ EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+ // we need the property names of the $select, in order to build the context URL
+ String selectList = odata.createUriHelper().buildContextURLSelectList(edmEntityType, expandOption, selectOption);
+ ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet)
+ .selectList(selectList)
+ .suffix(Suffix.ENTITY).build();
+
+ // make sure that $expand and $select are considered by the serializer
+ // adding the selectOption to the serializerOpts will actually tell the lib to do the job
+ EntitySerializerOptions opts = EntitySerializerOptions.with()
+ .contextURL(contextUrl)
+ .select(selectOption)
+ .expand(expandOption)
+ .build();
+
+ ODataSerializer serializer = this.odata.createSerializer(ODataFormat.fromContentType(responseFormat));
+ SerializerResult serializerResult = serializer.entity(srvMetadata, edmEntityType, entity, opts);
+
+ //5. configure the response object
+ response.setContent(serializerResult.getContent());
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
+ }
+
+
+
+ /*
+ * These processor methods are not handled in this tutorial
+ */
+
+ public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo,
+ ContentType requestFormat, ContentType responseFormat)
+ throws ODataApplicationException, DeserializerException, SerializerException {
+ throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+
+ public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo,
+ ContentType requestFormat, ContentType responseFormat)
+ throws ODataApplicationException, DeserializerException, SerializerException {
+ throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+
+ public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo)
+ throws ODataApplicationException {
+ throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java b/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java
new file mode 100755
index 0000000..c32c5c2
--- /dev/null
+++ b/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java
@@ -0,0 +1,150 @@
+/*
+ * 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 myservice.mynamespace.service;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Locale;
+
+import myservice.mynamespace.data.Storage;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.deserializer.DeserializerException;
+import org.apache.olingo.server.api.processor.PrimitiveProcessor;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.serializer.SerializerResult;
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.uri.UriParameter;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+import org.apache.olingo.server.api.uri.UriResourceProperty;
+
+public class DemoPrimitiveProcessor implements PrimitiveProcessor {
+
+ private OData odata;
+ private Storage storage;
+
+ public DemoPrimitiveProcessor(Storage storage) {
+ this.storage = storage;
+ }
+
+ public void init(OData odata, ServiceMetadata serviceMetadata) {
+ this.odata = odata;
+
+ }
+
+ /*
+ * In our example, the URL would be: http://localhost:8080/DemoService/DemoService.svc/Products(1)/Name
+ * and the response:
+ * {
+ *
+ * @odata.context: "$metadata#Products/Name",
+ * value: "Notebook Basic 15"
+ * }
+ */
+ public void readPrimitive(ODataRequest request, ODataResponse response,
+ UriInfo uriInfo, ContentType responseFormat)
+ throws ODataApplicationException, SerializerException {
+
+ // 1. Retrieve info from URI
+ // 1.1. retrieve the info about the requested entity set
+ List<UriResource> resourceParts = uriInfo.getUriResourceParts();
+ // Note: only in our example we can rely that the first segment is the EntitySet
+ UriResourceEntitySet uriEntityset = (UriResourceEntitySet) resourceParts.get(0);
+ EdmEntitySet edmEntitySet = uriEntityset.getEntitySet();
+ // the key for the entity
+ List<UriParameter> keyPredicates = uriEntityset.getKeyPredicates();
+
+ // 1.2. retrieve the requested (Edm) property
+ // the last segment is the Property
+ UriResourceProperty uriProperty = (UriResourceProperty) resourceParts.get(resourceParts.size() - 1);
+ EdmProperty edmProperty = uriProperty.getProperty();
+ String edmPropertyName = edmProperty.getName();
+ // in our example, we know we have only primitive types in our model
+ EdmPrimitiveType edmPropertyType = (EdmPrimitiveType) edmProperty.getType();
+
+ // 2. retrieve data from backend
+ // 2.1. retrieve the entity data, for which the property has to be read
+ Entity entity = storage.readEntityData(edmEntitySet, keyPredicates);
+ if (entity == null) { // Bad request
+ throw new ODataApplicationException("Entity not found",
+ HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
+ }
+
+ // 2.2. retrieve the property data from the entity
+ Property property = entity.getProperty(edmPropertyName);
+ if (property == null) {
+ throw new ODataApplicationException("Property not found",
+ HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
+ }
+
+ // 3. serialize
+ Object value = property.getValue();
+ if (value != null) {
+ // 3.1. configure the serializer
+ ODataFormat format = ODataFormat.fromContentType(responseFormat);
+ ODataSerializer serializer = odata.createSerializer(format);
+
+ ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).navOrPropertyPath(edmPropertyName).build();
+ PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextUrl).build();
+ // 3.2. serialize
+ SerializerResult serializerResult = serializer.primitive(edmPropertyType, property, options);
+ InputStream propertyStream = serializerResult.getContent();
+
+ // 4. configure the response object
+ response.setContent(propertyStream);
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
+ } else {
+ // in case there's no value for the property, we can skip the serialization
+ response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+ }
+ }
+
+ /*
+ * These processor methods are not handled in this tutorial
+ */
+
+ public void updatePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat,
+ ContentType responseFormat)
+ throws ODataApplicationException, DeserializerException, SerializerException {
+ throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+
+ public void deletePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo)
+ throws ODataApplicationException {
+ throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/util/Util.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/util/Util.java b/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/util/Util.java
new file mode 100755
index 0000000..f16360f
--- /dev/null
+++ b/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/util/Util.java
@@ -0,0 +1,149 @@
+/*
+ * 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 myservice.mynamespace.util;
+
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntityCollection;
+import org.apache.olingo.commons.api.edm.EdmBindingTarget;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmType;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.uri.UriParameter;
+
+public class Util {
+
+ public static Entity findEntity(EdmEntityType edmEntityType, EntityCollection entitySet,
+ List<UriParameter> keyParams) {
+
+ List<Entity> entityList = entitySet.getEntities();
+
+ // loop over all entities in order to find that one that matches
+ // all keys in request e.g. contacts(ContactID=1, CompanyID=1)
+ for (Entity entity : entityList) {
+ boolean foundEntity = entityMatchesAllKeys(edmEntityType, entity, keyParams);
+ if (foundEntity) {
+ return entity;
+ }
+ }
+
+ return null;
+ }
+
+ public static boolean entityMatchesAllKeys(EdmEntityType edmEntityType, Entity rt_entity,
+ List<UriParameter> keyParams) {
+
+ // loop over all keys
+ for (final UriParameter key : keyParams) {
+ // key
+ String keyName = key.getName();
+ String keyText = key.getText();
+
+ // note: below line doesn't consider: keyProp can be part of a complexType in V4
+ // in such case, it would be required to access it via getKeyPropertyRef()
+ // but since this isn't the case in our model, we ignore it in our implementation
+ EdmProperty edmKeyProperty = (EdmProperty) edmEntityType.getProperty(keyName);
+ // Edm: we need this info for the comparison below
+ Boolean isNullable = edmKeyProperty.isNullable();
+ Integer maxLength = edmKeyProperty.getMaxLength();
+ Integer precision = edmKeyProperty.getPrecision();
+ Boolean isUnicode = edmKeyProperty.isUnicode();
+ Integer scale = edmKeyProperty.getScale();
+ // get the EdmType in order to compare
+ EdmType edmType = edmKeyProperty.getType();
+ // if(EdmType instanceof EdmPrimitiveType) // do we need this?
+ EdmPrimitiveType edmPrimitiveType = (EdmPrimitiveType) edmType;
+
+ // Runtime data: the value of the current entity
+ // don't need to check for null, this is done in FWK
+ Object valueObject = rt_entity.getProperty(keyName).getValue();
+ // TODO if the property is a complex type
+
+ // now need to compare the valueObject with the keyText String
+ // this is done using the type.valueToString
+ String valueAsString = null;
+ try {
+ valueAsString = edmPrimitiveType.valueToString(valueObject, isNullable,
+ maxLength, precision, scale, isUnicode);
+ } catch (EdmPrimitiveTypeException e) {
+ return false; // TODO proper Exception handling
+ }
+
+ if (valueAsString == null) {
+ return false;
+ }
+
+ boolean matches = valueAsString.equals(keyText);
+ // if any of the key properties is not found in the entity, we don't need to search further
+ if (!matches) {
+ return false;
+ }
+ // if the given key value is found in the current entity, continue with the next key
+ }
+
+ return true;
+ }
+
+ /**
+ * Example:
+ * For the following navigation: DemoService.svc/Categories(1)/Products
+ * we need the EdmEntitySet for the navigation property "Products"
+ *
+ * This is defined as follows in the metadata:
+ * <code>
+ *
+ * <EntitySet Name="Categories" EntityType="OData.Demo.Category">
+ * <NavigationPropertyBinding Path="Products" Target="Products"/>
+ * </EntitySet>
+ * </code>
+ * The "Target" attribute specifies the target EntitySet
+ * Therefore we need the startEntitySet "Categories" in order to retrieve the target EntitySet "Products"
+ */
+ public static EdmEntitySet getNavigationTargetEntitySet(EdmEntitySet startEntitySet,
+ EdmNavigationProperty edmNavigationProperty)
+ throws ODataApplicationException {
+
+ EdmEntitySet navigationTargetEntitySet = null;
+
+ String navPropName = edmNavigationProperty.getName();
+ EdmBindingTarget edmBindingTarget = startEntitySet.getRelatedBindingTarget(navPropName);
+ if (edmBindingTarget == null) {
+ throw new ODataApplicationException("Not supported.",
+ HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+
+ if (edmBindingTarget instanceof EdmEntitySet) {
+ navigationTargetEntitySet = (EdmEntitySet) edmBindingTarget;
+ } else {
+ throw new ODataApplicationException("Not supported.",
+ HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+
+ return navigationTargetEntitySet;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/web/DemoServlet.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/web/DemoServlet.java b/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/web/DemoServlet.java
new file mode 100755
index 0000000..5c828e5
--- /dev/null
+++ b/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/web/DemoServlet.java
@@ -0,0 +1,75 @@
+/*
+ * 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 myservice.mynamespace.web;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import myservice.mynamespace.data.Storage;
+import myservice.mynamespace.service.DemoEdmProvider;
+import myservice.mynamespace.service.DemoEntityCollectionProcessor;
+import myservice.mynamespace.service.DemoEntityProcessor;
+import myservice.mynamespace.service.DemoPrimitiveProcessor;
+
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataHttpHandler;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.edmx.EdmxReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DemoServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+ private static final Logger LOG = LoggerFactory.getLogger(DemoServlet.class);
+
+ @Override
+ protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ try {
+ HttpSession session = req.getSession(true);
+ Storage storage = (Storage) session.getAttribute(Storage.class.getName());
+ if (storage == null) {
+ storage = new Storage();
+ session.setAttribute(Storage.class.getName(), storage);
+ }
+
+ // create odata handler and configure it with EdmProvider and Processor
+ OData odata = OData.newInstance();
+ ServiceMetadata edm = odata.createServiceMetadata(new DemoEdmProvider(), new ArrayList<EdmxReference>());
+ ODataHttpHandler handler = odata.createHandler(edm);
+ handler.register(new DemoEntityCollectionProcessor(storage));
+ handler.register(new DemoEntityProcessor(storage));
+ handler.register(new DemoPrimitiveProcessor(storage));
+
+ // let the handler do the work
+ handler.process(req, resp);
+ } catch (RuntimeException e) {
+ LOG.error("Server Error occurred in DemoServlet", e);
+ throw new ServletException(e);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p6_queryoptions-es/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/samples/tutorials/p6_queryoptions-es/src/main/webapp/WEB-INF/web.xml b/samples/tutorials/p6_queryoptions-es/src/main/webapp/WEB-INF/web.xml
new file mode 100755
index 0000000..bc216cb
--- /dev/null
+++ b/samples/tutorials/p6_queryoptions-es/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,34 @@
+<?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.
+-->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
+
+ <servlet>
+ <servlet-name>DemoServlet</servlet-name>
+ <servlet-class> myservice.mynamespace.web.DemoServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>DemoServlet</servlet-name>
+ <url-pattern>/DemoService.svc/*</url-pattern>
+ </servlet-mapping>
+</web-app>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p6_queryoptions-es/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/samples/tutorials/p6_queryoptions-es/src/main/webapp/index.jsp b/samples/tutorials/p6_queryoptions-es/src/main/webapp/index.jsp
new file mode 100755
index 0000000..cee3a31
--- /dev/null
+++ b/samples/tutorials/p6_queryoptions-es/src/main/webapp/index.jsp
@@ -0,0 +1,43 @@
+<!--
+
+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.
+
+-->
+<html>
+<body>
+<h2>Hello World!</h2>
+<a href="DemoService.svc/">OData Olingo V4 Demo Service - Expand and Select</a>
+<h3>Sample Links</h3>
+<ul>
+ <li>
+ <a href="DemoService.svc/Products(1)/?$expand=Category">Expand - /Products(1)/?$expand=Category</a>
+ </li>
+ <li>
+ <a href="DemoService.svc/Products/?$expand=Category">Expand - /Products/?$expand=Category</a>
+ </li>
+ <li>
+ <a href="DemoService.svc/Categories(1)/?$expand=Products">Expand - /Categories(1)/?$expand=Products</a>
+ </li>
+ <li>
+ <a href="DemoService.svc/Categories/?$expand=Products">Expand - /DemoService.svc/Categories/?$expand=Products</a>
+ </li>
+</ul>
+
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/pom.xml
----------------------------------------------------------------------
diff --git a/samples/tutorials/pom.xml b/samples/tutorials/pom.xml
index 111e200..cfa48a4 100644
--- a/samples/tutorials/pom.xml
+++ b/samples/tutorials/pom.xml
@@ -39,7 +39,8 @@
<module>p2_readep</module>
<module>p3_write</module>
<module>p4_navigation</module>
- <module>p5_queryoptions</module>
+ <module>p5_queryoptions-tis</module>
+ <module>p6_queryoptions-es</module>
</modules>
<build>
[15/18] olingo-odata4 git commit: [OLINGO-708] Enabled async support
for batch case in TecSvc
Posted by ch...@apache.org.
[OLINGO-708] Enabled async support for batch case in TecSvc
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/95582338
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/95582338
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/95582338
Branch: refs/heads/OLINGO-640
Commit: 955823383d8755cace6872e2f9f6b72db22c885d
Parents: 5e481b2
Author: Michael Bolz <mi...@sap.com>
Authored: Mon Aug 3 19:21:38 2015 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Mon Aug 3 19:22:34 2015 +0200
----------------------------------------------------------------------
.../fit/tecsvc/client/AsyncSupportITCase.java | 104 ++++++++
.../fit/tecsvc/http/BasicAsyncITCase.java | 238 +++++++++++++++++++
fit/src/test/resources/basicBatchPost.batch | 33 +++
.../processor/TechnicalBatchProcessor.java | 17 ++
4 files changed, 392 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/95582338/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AsyncSupportITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AsyncSupportITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AsyncSupportITCase.java
index ad8fcbc..b99317d 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AsyncSupportITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AsyncSupportITCase.java
@@ -19,9 +19,15 @@
package org.apache.olingo.fit.tecsvc.client;
import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.client.api.communication.ODataClientErrorException;
+import org.apache.olingo.client.api.communication.request.AsyncBatchRequestWrapper;
+import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
import org.apache.olingo.client.api.communication.request.ODataRequest;
+import org.apache.olingo.client.api.communication.request.batch.ODataBatchRequest;
import org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateRequest;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
import org.apache.olingo.client.api.communication.response.AsyncResponseWrapper;
+import org.apache.olingo.client.api.communication.response.ODataBatchResponse;
import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse;
import org.apache.olingo.client.api.communication.response.ODataResponse;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
@@ -29,6 +35,7 @@ import org.apache.olingo.client.api.domain.ClientEntity;
import org.apache.olingo.client.api.domain.ClientEntitySet;
import org.apache.olingo.client.api.domain.ClientObjectFactory;
import org.apache.olingo.client.api.domain.ClientProperty;
+import org.apache.olingo.client.api.uri.URIBuilder;
import org.apache.olingo.client.core.ODataClientFactory;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntityCollection;
@@ -40,9 +47,11 @@ import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.fit.AbstractBaseTestITCase;
import org.apache.olingo.fit.tecsvc.TecSvcConst;
import org.apache.olingo.server.tecsvc.async.TechnicalAsyncService;
+import org.junit.Ignore;
import org.junit.Test;
import java.net.URI;
+import java.net.URISyntaxException;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -198,6 +207,101 @@ public final class AsyncSupportITCase extends AbstractBaseTestITCase {
assertNull(property2.getPrimitiveValue());
}
+ @Test
+ @Ignore("mibo: Does currently not work as expected -> issue in ODataClient?")
+ public void getBatchRequest() throws Exception {
+ ODataClient client = getClient();
+ final ODataBatchRequest request = client.getBatchRequestFactory().getBatchRequest(SERVICE_URI);
+
+// final BatchManager payload = request.payloadManager();
+
+ // create new request
+// ODataEntityRequest<ClientEntity> getRequest = appendGetRequest(client, payload, "ESAllPrim", 32767, false);
+// payload.addRequest(getRequest);
+
+ //
+ request.addCustomHeader(HttpHeader.PREFER,
+ "respond-async; " + TechnicalAsyncService.TEC_ASYNC_SLEEP + "=1");
+ ODataBatchableRequest getRequest = appendGetRequest(client, "ESAllPrim", 32767, false);
+ AsyncBatchRequestWrapper asyncRequest =
+ client.getAsyncRequestFactory().getAsyncBatchRequestWrapper(request);
+ asyncRequest.addRetrieve(getRequest);
+ AsyncResponseWrapper<ODataBatchResponse> asyncResponse = asyncRequest.execute();
+
+// Future<ODataBatchResponse> test = payload.getAsyncResponse();
+// ODataBatchResponse res = payload.getResponse();
+//
+// while(!test.isDone()) {
+// System.out.println("Wait...");
+// TimeUnit.SECONDS.sleep(1);
+// }
+
+// // Fetch result
+// final ODataBatchResponse response = asyncResponse.getODataResponse();
+
+ waitTillDone(asyncResponse, 3);
+// assertEquals(HttpStatusCode.ACCEPTED.getStatusCode(), response.getStatusCode());
+// assertEquals("Accepted", response.getStatusMessage());
+
+ ODataResponse firstResponse = asyncResponse.getODataResponse();
+ assertEquals(200, firstResponse.getStatusCode());
+ assertEquals(2, firstResponse.getHeaderNames().size());
+ assertEquals("4.0", firstResponse.getHeader("OData-Version").iterator().next());
+
+ ResWrap<Entity> firWrap = getClient().getDeserializer(ContentType.APPLICATION_JSON)
+ .toEntity(firstResponse.getRawResponse());
+ Entity entity = firWrap.getPayload();
+ assertEquals(32767, entity.getProperty("PropertyInt16").asPrimitive());
+ assertEquals("First Resource - positive values", entity.getProperty("PropertyString").asPrimitive());
+ }
+
+
+ /**
+ * Test delete with async prefer header but without async support from TecSvc.
+ */
+ @Test
+ public void deleteEntity() throws Exception {
+ ODataClient client = getClient();
+ URI uri = client.newURIBuilder(SERVICE_URI)
+ .appendEntitySetSegment(ES_ALL_PRIM)
+ .appendKeySegment(32767).build();
+
+ // asyncDeleteRequest async request
+ ODataRequest deleteRequest = getClient().getCUDRequestFactory().getDeleteRequest(uri)
+ .addCustomHeader(HttpHeader.PREFER, "respond-async; " + TechnicalAsyncService.TEC_ASYNC_SLEEP + "=5");
+ AsyncResponseWrapper<ODataResponse> asyncDeleteRequest =
+ client.getAsyncRequestFactory().getAsyncRequestWrapper(deleteRequest).execute();
+
+ waitTillDone(asyncDeleteRequest, 5);
+
+ ODataResponse response = asyncDeleteRequest.getODataResponse();
+ assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode());
+
+ // Check that the deleted entity is really gone.
+ // This check has to be in the same session in order to access the same data provider.
+ ODataEntityRequest<ClientEntity> entityRequest = client.getRetrieveRequestFactory().getEntityRequest(uri);
+ entityRequest.addCustomHeader(HttpHeader.COOKIE, response.getHeader(HttpHeader.SET_COOKIE).iterator().next());
+ try {
+ entityRequest.execute();
+ fail("Expected exception not thrown!");
+ } catch (final ODataClientErrorException e) {
+ assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), e.getStatusLine().getStatusCode());
+ }
+ }
+
+ private ODataEntityRequest<ClientEntity> appendGetRequest(final ODataClient client, final String segment,
+ final Object key, final boolean isRelative)
+ throws URISyntaxException {
+
+ final URIBuilder targetURI = client.newURIBuilder(SERVICE_URI);
+ targetURI.appendEntitySetSegment(segment).appendKeySegment(key);
+ final URI uri = (isRelative) ? new URI(SERVICE_URI).relativize(targetURI.build()) : targetURI.build();
+
+ ODataEntityRequest<ClientEntity> queryReq = client.getRetrieveRequestFactory().getEntityRequest(uri);
+ queryReq.setFormat(ContentType.JSON);
+ return queryReq;
+ }
+
private void checkEntityAvailableWith(ClientEntitySet entitySet, String property, Object value) {
List<ClientEntity> entities = entitySet.getEntities();
for (ClientEntity entity : entities) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/95582338/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicAsyncITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicAsyncITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicAsyncITCase.java
new file mode 100644
index 0000000..c4a6779
--- /dev/null
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicAsyncITCase.java
@@ -0,0 +1,238 @@
+/*
+ * 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.tecsvc.http;
+
+import org.apache.olingo.client.api.ODataClient;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpMethod;
+import org.apache.olingo.fit.AbstractBaseTestITCase;
+import org.apache.olingo.fit.tecsvc.TecSvcConst;
+import org.apache.olingo.fit.util.StringHelper;
+import org.apache.olingo.server.tecsvc.async.TechnicalAsyncService;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Test support of asynchronous batch within the TecSvc without using the OData client library (only
+ * use java.net.* components for plain http communication).
+ */
+public class BasicAsyncITCase extends AbstractBaseTestITCase {
+
+ private static final String SERVICE_URI = TecSvcConst.BASE_URI + "/";
+
+ private static final String HEADER_CONTENT_TRANSFER_ENCODING_BINARY = "Content-Transfer-Encoding: binary";
+ private static final String HEADER_CONTENT_TYPE_HTTP =
+ HttpHeader.CONTENT_TYPE + ": " + ContentType.APPLICATION_HTTP.toContentTypeString();
+ private static final String DEFAULT_BATCH_BOUNDARY = "batch_123";
+ private static final String ACCEPT_HEADER_VALUE = ContentType.APPLICATION_JSON.toContentTypeString();
+
+ private static final String CRLF = "\r\n";
+ private static final String DEFAULT_ENCODING = "utf-8";
+
+ /**
+ * Works
+ */
+ @Test
+ public void batchAsync() throws Exception {
+ final String content = getDefaultRequest("ESAllPrim(32767)");
+ final HttpURLConnection connection = postBatch(StringHelper.encapsulate(content), DEFAULT_BATCH_BOUNDARY, 1);
+ StringHelper.Stream response = StringHelper.toStream(connection.getInputStream());
+
+ assertEquals(0, response.byteLength());
+
+ Map<String, List<String>> headerFields = connection.getHeaderFields();
+ assertEquals("HTTP/1.1 202 Accepted", headerFields.get(null).get(0));
+ assertTrue(Pattern.matches("http:\\/\\/localhost:9080\\/odata-server-tecsvc\\/status\\/\\d*",
+ headerFields.get("Location").get(0)));
+ assertEquals("respond-async", headerFields.get("Preference-Applied").get(0));
+
+ // get async response (still pending)
+ String respondUri = headerFields.get("Location").get(0);
+ HttpURLConnection statusRequest = getRequest(new URL(respondUri), Collections.<String, String>emptyMap());
+ StringHelper.Stream statusBody = StringHelper.toStream(statusRequest.getInputStream());
+ Map<String, List<String>> statusHeaderFields = statusRequest.getHeaderFields();
+ assertEquals("HTTP/1.1 202 Accepted", statusHeaderFields.get(null).get(0));
+ assertEquals(0, statusBody.byteLength());
+
+ // get async response (now finished)
+ TimeUnit.SECONDS.sleep(2);
+ HttpURLConnection result = getRequest(new URL(respondUri), Collections.<String, String>emptyMap());
+ StringHelper.Stream resultBody = StringHelper.toStream(result.getInputStream());
+ Map<String, List<String>> resultHeaderFields = result.getHeaderFields();
+ String resBody = resultBody.asString();
+
+ assertEquals("HTTP/1.1 200 OK", resultHeaderFields.get(null).get(0));
+ assertEquals(1013, resultBody.byteLength());
+ contains(resBody,
+ "HTTP/1.1 200 OK",
+ "OData-Version: 4.0",
+ "Content-Length: 605",
+ "\"@odata.context\":\"$metadata#ESAllPrim/$entity\"",
+ "\"PropertyInt16\":32767",
+ "\"PropertyGuid\":\"01234567-89ab-cdef-0123-456789abcdef\",",
+ "--batch_", "--");
+ }
+
+ /**
+ * Test with changeset
+ */
+ @Test
+ public void asyncChangesetViaPost() throws Exception {
+ InputStream content = Thread.currentThread().getContextClassLoader().getResourceAsStream("basicBatchPost.batch");
+ final HttpURLConnection connection = postBatch(content, "batch_8194-cf13-1f56", 1);
+ StringHelper.Stream response = StringHelper.toStream(connection.getInputStream());
+ assertEquals(0, response.byteLength());
+
+ Map<String, List<String>> headerFields = connection.getHeaderFields();
+ assertEquals("HTTP/1.1 202 Accepted", headerFields.get(null).get(0));
+ // because of generated status id it is only checked that the location starts correct and contains a number
+ assertTrue(Pattern.matches("http:\\/\\/localhost:9080\\/odata-server-tecsvc\\/status\\/\\d*",
+ headerFields.get("Location").get(0)));
+ assertEquals("respond-async", headerFields.get("Preference-Applied").get(0));
+
+ // get async response (still pending)
+ String respondUri = headerFields.get("Location").get(0);
+ HttpURLConnection statusRequest = getRequest(new URL(respondUri), Collections.<String, String>emptyMap());
+ StringHelper.Stream statusBody = StringHelper.toStream(statusRequest.getInputStream());
+ Map<String, List<String>> statusHeaderFields = statusRequest.getHeaderFields();
+ assertEquals("HTTP/1.1 202 Accepted", statusHeaderFields.get(null).get(0));
+ assertEquals(0, statusBody.byteLength());
+
+ // get async response (now finished)
+ TimeUnit.SECONDS.sleep(2);
+ HttpURLConnection result = getRequest(new URL(respondUri), Collections.<String, String>emptyMap());
+ StringHelper.Stream resultBody = StringHelper.toStream(result.getInputStream());
+ Map<String, List<String>> resultHeaderFields = result.getHeaderFields();
+ String resBody = resultBody.asString();
+ assertEquals("HTTP/1.1 200 OK", resultHeaderFields.get(null).get(0));
+ assertEquals(2324, resultBody.byteLength());
+ contains(resBody,
+ "HTTP/1.1 200 OK",
+ "OData-Version: 4.0",
+ "Content-Length: 605",
+ "\"@odata.context\":\"$metadata#ESAllPrim/$entity\"",
+ "\"PropertyInt16\":32767",
+ "\"PropertyGuid\":\"01234567-89ab-cdef-0123-456789abcdef\",",
+ "--batch_", "--");
+ }
+
+ /**
+ * Validates that the content contains all given values in same order as the parameters are given.
+ * If the content does not contain a value or not in the given order <code>Assert.fail()</code> is called.
+ *
+ * @param content content which is checked
+ * @param values values which must be in content (and in correct order)
+ */
+ private void contains(String content, String... values) {
+ int index = 0;
+ for (String value : values) {
+ int currentIndex = content.indexOf(value, index);
+ if(currentIndex == -1) {
+ if(content.contains(value)) {
+ int foundIndex = content.indexOf(value);
+ fail("Expected value '" + value + "' was found but not were expected " +
+ "(started to search from position '" + index + "' but found first occurrence at index '" +
+ foundIndex + "').");
+ } else {
+ fail("Expected value '" + value + "' was not found");
+ }
+ }
+ index = currentIndex;
+ }
+ }
+
+ private String getDefaultRequest(final String uri) {
+ return "--" + DEFAULT_BATCH_BOUNDARY + CRLF
+ + HEADER_CONTENT_TRANSFER_ENCODING_BINARY + CRLF
+ + HEADER_CONTENT_TYPE_HTTP + CRLF
+ + CRLF
+ + "GET " + uri + " HTTP/1.1" + CRLF
+ + CRLF
+ + CRLF
+ + "--" + DEFAULT_BATCH_BOUNDARY + "--";
+ }
+
+ private HttpURLConnection postRequest(final URL url, final String content, final Map<String, String> headers)
+ throws IOException {
+ final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.POST.toString());
+ //
+ for (Map.Entry<String, String> header : headers.entrySet()) {
+ connection.setRequestProperty(header.getKey(), header.getValue());
+ }
+ //
+ connection.setDoOutput(true);
+ final OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
+ writer.append(content);
+ writer.close();
+ connection.connect();
+ return connection;
+ }
+
+ private HttpURLConnection getRequest(URL url, Map<String, String> headers) throws IOException {
+ final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod(HttpMethod.GET.toString());
+ //
+ for (Map.Entry<String, String> header : headers.entrySet()) {
+ connection.setRequestProperty(header.getKey(), header.getValue());
+ }
+ //
+ connection.connect();
+ return connection;
+ }
+
+ private HttpURLConnection postBatch(final InputStream content, String batchBoundary, int sleepTime)
+ throws IOException {
+
+ Map<String, String> headers = new HashMap<String, String>();
+ String contentTypeValue = ContentType.create(
+ ContentType.MULTIPART_MIXED, "boundary", batchBoundary).toContentTypeString();
+ headers.put(HttpHeader.CONTENT_TYPE, contentTypeValue);
+ headers.put(HttpHeader.ACCEPT, ACCEPT_HEADER_VALUE);
+ if(sleepTime >= 0) {
+ headers.put(HttpHeader.PREFER, "respond-async; " +
+ TechnicalAsyncService.TEC_ASYNC_SLEEP + "=" + String.valueOf(sleepTime));
+ }
+
+ StringHelper.Stream s = StringHelper.toStream(content);
+ final URL url = new URL(SERVICE_URI + "$batch");
+ return postRequest(url, s.asString(DEFAULT_ENCODING), headers);
+ }
+
+ @Override
+ protected ODataClient getClient() {
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/95582338/fit/src/test/resources/basicBatchPost.batch
----------------------------------------------------------------------
diff --git a/fit/src/test/resources/basicBatchPost.batch b/fit/src/test/resources/basicBatchPost.batch
new file mode 100644
index 0000000..ad5f617
--- /dev/null
+++ b/fit/src/test/resources/basicBatchPost.batch
@@ -0,0 +1,33 @@
+--batch_8194-cf13-1f56
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+GET ESAllPrim(32767) HTTP/1.1
+Accept: application/json
+
+
+--batch_8194-cf13-1f56
+Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd
+
+--changeset_f980-1cb6-94dd
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+Content-ID: changeRequest1
+
+PUT ESAllPrim(32767) HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+
+{"PropertyString":"MODIFIED"}
+
+--changeset_f980-1cb6-94dd--
+
+--batch_8194-cf13-1f56
+Content-Type: application/http
+Content-Transfer-Encoding: binary
+
+GET ESAllPrim(32767)/PropertyString HTTP/1.1
+Accept: application/json
+
+
+--batch_8194-cf13-1f56--
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/95582338/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalBatchProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalBatchProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalBatchProcessor.java
index a2c7629..6821c8f 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalBatchProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalBatchProcessor.java
@@ -36,6 +36,8 @@ import org.apache.olingo.server.api.deserializer.batch.BatchRequestPart;
import org.apache.olingo.server.api.deserializer.batch.ODataResponsePart;
import org.apache.olingo.server.api.prefer.PreferencesApplied;
import org.apache.olingo.server.api.processor.BatchProcessor;
+import org.apache.olingo.server.tecsvc.async.AsyncProcessor;
+import org.apache.olingo.server.tecsvc.async.TechnicalAsyncService;
import org.apache.olingo.server.tecsvc.data.DataProvider;
public class TechnicalBatchProcessor extends TechnicalProcessor implements BatchProcessor {
@@ -47,6 +49,21 @@ public class TechnicalBatchProcessor extends TechnicalProcessor implements Batch
@Override
public void processBatch(final BatchFacade facade, final ODataRequest request, final ODataResponse response)
throws ODataApplicationException, ODataLibraryException {
+ // only the first batch call (process batch) must be handled in a separate way for async support
+ // because a changeset has to be wrapped within a process batch call
+ if(odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).hasRespondAsync()) {
+ TechnicalAsyncService asyncService = TechnicalAsyncService.getInstance();
+ BatchProcessor processor = new TechnicalBatchProcessor(dataProvider);
+ processor.init(odata, serviceMetadata);
+ AsyncProcessor<BatchProcessor> asyncProcessor = asyncService.register(processor, BatchProcessor.class);
+ asyncProcessor.prepareFor().processBatch(facade, request, response);
+ String location = asyncProcessor.processAsync();
+ TechnicalAsyncService.acceptedResponse(response, location);
+ //
+ return;
+ }
+
+
final boolean continueOnError =
odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).hasContinueOnError();
[05/18] olingo-odata4 git commit: [OLINGO-713] Added tutorial project
for system query options
Posted by ch...@apache.org.
[OLINGO-713] Added tutorial project for system query options
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/010d94f7
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/010d94f7
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/010d94f7
Branch: refs/heads/OLINGO-640
Commit: 010d94f7f762f49db1668d8a008bc639e9df783e
Parents: fb65199
Author: Michael Bolz <mi...@sap.com>
Authored: Fri Jul 24 15:50:56 2015 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Fri Jul 24 15:50:56 2015 +0200
----------------------------------------------------------------------
samples/tutorials/p5_queryoptions/pom.xml | 79 ++++++++++
.../myservice/mynamespace/data/Storage.java | 130 ++++++++++++++++
.../mynamespace/service/DemoEdmProvider.java | 154 +++++++++++++++++++
.../service/DemoEntityCollectionProcessor.java | 142 +++++++++++++++++
.../service/DemoEntityProcessor.java | 118 ++++++++++++++
.../service/DemoPrimitiveProcessor.java | 150 ++++++++++++++++++
.../java/myservice/mynamespace/util/Util.java | 105 +++++++++++++
.../myservice/mynamespace/web/DemoServlet.java | 76 +++++++++
.../src/main/webapp/WEB-INF/web.xml | 40 +++++
.../p5_queryoptions/src/main/webapp/index.jsp | 26 ++++
samples/tutorials/pom.xml | 1 +
11 files changed, 1021 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/010d94f7/samples/tutorials/p5_queryoptions/pom.xml
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/pom.xml b/samples/tutorials/p5_queryoptions/pom.xml
new file mode 100755
index 0000000..117f59d
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions/pom.xml
@@ -0,0 +1,79 @@
+<?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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>my.group.id</groupId>
+ <artifactId>DemoService-QueryOptions</artifactId>
+ <packaging>war</packaging>
+ <version>0.0.1</version>
+
+ <name>${project.artifactId}-Webapp</name>
+
+ <build>
+ <finalName>DemoService</finalName>
+ </build>
+
+ <properties>
+ <javax.version>2.5</javax.version>
+ <odata.version>4.0.0-beta-03</odata.version>
+ <slf4j.version>1.7.7</slf4j.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>${javax.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>odata-server-api</artifactId>
+ <version>${odata.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>odata-server-core</artifactId>
+ <version>${odata.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>odata-commons-api</artifactId>
+ <version>${odata.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>odata-commons-core</artifactId>
+ <version>${odata.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>${slf4j.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/010d94f7/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/data/Storage.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/data/Storage.java b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/data/Storage.java
new file mode 100755
index 0000000..2aa9fac
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/data/Storage.java
@@ -0,0 +1,130 @@
+/*
+ * 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 myservice.mynamespace.data;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import myservice.mynamespace.service.DemoEdmProvider;
+import myservice.mynamespace.util.Util;
+
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntityCollection;
+import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.data.ValueType;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.uri.UriParameter;
+
+public class Storage {
+
+ private List<Entity> productList;
+
+ public Storage() {
+ productList = new ArrayList<Entity>();
+ initSampleData();
+ }
+
+ /* PUBLIC FACADE */
+
+ public EntityCollection readEntitySetData(EdmEntitySet edmEntitySet)throws ODataApplicationException{
+
+ // actually, this is only required if we have more than one Entity Sets
+ if(edmEntitySet.getName().equals(DemoEdmProvider.ES_PRODUCTS_NAME)){
+ return getProducts();
+ }
+
+ return null;
+ }
+
+ public Entity readEntityData(EdmEntitySet edmEntitySet, List<UriParameter> keyParams)
+ throws ODataApplicationException{
+
+ EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+
+ // actually, this is only required if we have more than one Entity Type
+ if(edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)){
+ return getProduct(edmEntityType, keyParams);
+ }
+
+ return null;
+ }
+
+
+
+ /* INTERNAL */
+
+ private EntityCollection getProducts(){
+ EntityCollection retEntitySet = new EntityCollection();
+
+ for(Entity productEntity : this.productList){
+ retEntitySet.getEntities().add(productEntity);
+ }
+
+ return retEntitySet;
+ }
+
+
+ private Entity getProduct(EdmEntityType edmEntityType, List<UriParameter> keyParams)
+ throws ODataApplicationException{
+
+ // the list of entities at runtime
+ EntityCollection entitySet = getProducts();
+
+ /* generic approach to find the requested entity */
+ Entity requestedEntity = Util.findEntity(edmEntityType, entitySet, keyParams);
+
+ if(requestedEntity == null){
+ // this variable is null if our data doesn't contain an entity for the requested key
+ // Throw suitable exception
+ throw new ODataApplicationException("Entity for requested key doesn't exist",
+ HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
+ }
+
+ return requestedEntity;
+ }
+
+ /* HELPER */
+
+ private void initSampleData(){
+
+ // add some sample product entities
+ productList.add(new Entity()
+ .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1))
+ .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Basic 15"))
+ .addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
+ "Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 40GB")));
+
+ productList.add(new Entity()
+ .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2))
+ .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "1UMTS PDA"))
+ .addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
+ "Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network")));
+
+ productList.add(new Entity()
+ .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3))
+ .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Ergo Screen"))
+ .addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
+ "19 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960")));
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/010d94f7/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
new file mode 100755
index 0000000..3c28a21
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
@@ -0,0 +1,154 @@
+/*
+ * 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 myservice.mynamespace.service;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.olingo.commons.api.ODataException;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
+import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
+import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo;
+import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet;
+import org.apache.olingo.commons.api.edm.provider.CsdlEntityType;
+import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
+import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef;
+import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
+
+public class DemoEdmProvider extends CsdlAbstractEdmProvider {
+
+ // Service Namespace
+ public static final String NAMESPACE = "OData.Demo";
+
+ // EDM Container
+ public static final String CONTAINER_NAME = "Container";
+ public static final FullQualifiedName CONTAINER = new FullQualifiedName(NAMESPACE, CONTAINER_NAME);
+
+ // Entity Types Names
+ public static final String ET_PRODUCT_NAME = "Product";
+ public static final FullQualifiedName ET_PRODUCT_FQN = new FullQualifiedName(NAMESPACE, ET_PRODUCT_NAME);
+
+ // Entity Set Names
+ public static final String ES_PRODUCTS_NAME = "Products";
+
+ @Override
+ public CsdlEntityType getEntityType(FullQualifiedName entityTypeName)
+ throws ODataException {
+ // this method is called for one of the EntityTypes that are configured in the Schema
+ if (ET_PRODUCT_FQN.equals(entityTypeName)) {
+
+ // create EntityType properties
+ CsdlProperty id = new CsdlProperty().setName("ID").setType(
+ EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
+ CsdlProperty name = new CsdlProperty().setName("Name").setType(
+ EdmPrimitiveTypeKind.String.getFullQualifiedName());
+ CsdlProperty description = new CsdlProperty().setName("Description").setType(
+ EdmPrimitiveTypeKind.String.getFullQualifiedName());
+
+ // create PropertyRef for Key element
+ CsdlPropertyRef propertyRef = new CsdlPropertyRef();
+ propertyRef.setName("ID");
+
+ // configure EntityType
+ CsdlEntityType entityType = new CsdlEntityType();
+ entityType.setName(ET_PRODUCT_NAME);
+ entityType.setProperties(Arrays.asList(id, name, description));
+ entityType.setKey(Collections.singletonList(propertyRef));
+
+ return entityType;
+ }
+
+ return null;
+
+ }
+
+ @Override
+ public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer,
+ String entitySetName) throws ODataException {
+ if (entityContainer.equals(CONTAINER)) {
+ if (entitySetName.equals(ES_PRODUCTS_NAME)) {
+ CsdlEntitySet entitySet = new CsdlEntitySet();
+ entitySet.setName(ES_PRODUCTS_NAME);
+ entitySet.setType(ET_PRODUCT_FQN);
+
+ return entitySet;
+ }
+ }
+
+ return null;
+
+ }
+
+ @Override
+ public CsdlEntityContainerInfo getEntityContainerInfo(
+ FullQualifiedName entityContainerName) throws ODataException {
+ // This method is invoked when displaying the service document at
+ // e.g. http://localhost:8080/DemoService/DemoService.svc
+ if (entityContainerName == null || entityContainerName.equals(CONTAINER)) {
+ CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo();
+ entityContainerInfo.setContainerName(CONTAINER);
+ return entityContainerInfo;
+ }
+
+ return null;
+
+ }
+
+ @Override
+ public List<CsdlSchema> getSchemas() throws ODataException {
+ // create Schema
+ CsdlSchema schema = new CsdlSchema();
+ schema.setNamespace(NAMESPACE);
+
+ // add EntityTypes
+ List<CsdlEntityType> entityTypes = new ArrayList<CsdlEntityType>();
+ entityTypes.add(getEntityType(ET_PRODUCT_FQN));
+ schema.setEntityTypes(entityTypes);
+
+ // add EntityContainer
+ schema.setEntityContainer(getEntityContainer());
+
+ // finally
+ List<CsdlSchema> schemas = new ArrayList<CsdlSchema>();
+ schemas.add(schema);
+
+ return schemas;
+
+ }
+
+ @Override
+ public CsdlEntityContainer getEntityContainer() throws ODataException {
+ // create EntitySets
+ List<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();
+ entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME));
+
+ // create EntityContainer
+ CsdlEntityContainer entityContainer = new CsdlEntityContainer();
+ entityContainer.setName(CONTAINER_NAME);
+ entityContainer.setEntitySets(entitySets);
+
+ return entityContainer;
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/010d94f7/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java
new file mode 100755
index 0000000..fc58c23
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.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 myservice.mynamespace.service;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Locale;
+
+import myservice.mynamespace.data.Storage;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntityCollection;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
+import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.serializer.SerializerResult;
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+import org.apache.olingo.server.api.uri.queryoption.CountOption;
+import org.apache.olingo.server.api.uri.queryoption.SkipOption;
+import org.apache.olingo.server.api.uri.queryoption.TopOption;
+
+public class DemoEntityCollectionProcessor implements EntityCollectionProcessor {
+
+ private OData odata;
+ private ServiceMetadata serviceMetadata;
+ private Storage storage;
+
+ public DemoEntityCollectionProcessor(Storage storage) {
+ this.storage = storage;
+ }
+
+ public void init(OData odata, ServiceMetadata serviceMetadata) {
+ this.odata = odata;
+ this.serviceMetadata = serviceMetadata;
+ }
+
+ public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo,
+ ContentType responseFormat) throws ODataApplicationException, SerializerException {
+
+ // 1st retrieve the requested EntitySet from the uriInfo (representation of the parsed URI)
+ List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+ // in our example, the first segment is the EntitySet
+ UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
+ EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
+
+ // 2nd: fetch the data from backend for this requested EntitySetName and deliver as EntitySet
+ EntityCollection entityCollection = storage.readEntitySetData(edmEntitySet);
+
+ // 3rd: apply System Query Options
+ // modify the result set according to the query options, specified by the end user
+ List<Entity> entityList = entityCollection.getEntities();
+ EntityCollection returnEntityCollection = new EntityCollection();
+
+ // handle $count: always return the original number of entities, without considering $top and $skip
+ CountOption countOption = uriInfo.getCountOption();
+ if (countOption != null) {
+ boolean isCount = countOption.getValue();
+ if (isCount) {
+ returnEntityCollection.setCount(entityList.size());
+ }
+ }
+
+ // handle $skip
+ SkipOption skipOption = uriInfo.getSkipOption();
+ if (skipOption != null) {
+ int skipNumber = skipOption.getValue();
+ if (skipNumber >= 0 && skipNumber <= entityList.size()) {
+ entityList = entityList.subList(skipNumber, entityList.size());
+ } else {
+ throw new ODataApplicationException("Invalid value for $skip", HttpStatusCode.BAD_REQUEST.getStatusCode(),
+ Locale.ROOT);
+ }
+ }
+
+ // handle $top
+ TopOption topOption = uriInfo.getTopOption();
+ if (topOption != null) {
+ int topNumber = topOption.getValue();
+ if (topNumber >= 0 && topNumber <= entityList.size()) {
+ entityList = entityList.subList(0, topNumber);
+ } else {
+ throw new ODataApplicationException("Invalid value for $top", HttpStatusCode.BAD_REQUEST.getStatusCode(),
+ Locale.ROOT);
+ }
+ }
+
+ // after applying the system query options, create the EntityCollection based on the reduced list
+ for (Entity entity : entityList) {
+ returnEntityCollection.getEntities().add(entity);
+ }
+
+ // 4th: create a serializer based on the requested format (json)
+ ODataFormat format = ODataFormat.fromContentType(responseFormat);
+ ODataSerializer serializer = odata.createSerializer(format);
+
+ // and serialize the content: transform from the EntitySet object to InputStream
+ EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+ ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build();
+
+ EntityCollectionSerializerOptions opts =
+ EntityCollectionSerializerOptions.with().contextURL(contextUrl).count(countOption).build();
+ SerializerResult serializerResult =
+ serializer.entityCollection(serviceMetadata, edmEntityType, returnEntityCollection, opts);
+ InputStream serializedContent = serializerResult.getContent();
+
+ // 5th: configure the response object: set the body, headers and status code
+ response.setContent(serializedContent);
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/010d94f7/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java
new file mode 100755
index 0000000..81453a0
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java
@@ -0,0 +1,118 @@
+/*
+ * 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 myservice.mynamespace.service;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Locale;
+
+import myservice.mynamespace.data.Storage;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.deserializer.DeserializerException;
+import org.apache.olingo.server.api.processor.EntityProcessor;
+import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.serializer.SerializerResult;
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.uri.UriParameter;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+
+public class DemoEntityProcessor implements EntityProcessor {
+
+ private OData odata;
+ private ServiceMetadata serviceMetadata;
+ private Storage storage;
+
+ public DemoEntityProcessor(Storage storage) {
+ this.storage = storage;
+ }
+
+ public void init(OData odata, ServiceMetadata serviceMetadata) {
+ this.odata = odata;
+ this.serviceMetadata = serviceMetadata;
+ }
+
+ public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
+ throws ODataApplicationException, SerializerException {
+
+ // 1. retrieve the Entity Type
+ List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+ // Note: only in our example we can assume that the first segment is the EntitySet
+ UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
+ EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
+
+ // 2. retrieve the data from backend
+ List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
+ Entity entity = storage.readEntityData(edmEntitySet, keyPredicates);
+
+ // 3. serialize
+ EdmEntityType entityType = edmEntitySet.getEntityType();
+
+ ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).suffix(ContextURL.Suffix.ENTITY).build();
+ // expand and select currently not supported
+ EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build();
+
+ ODataFormat oDataFormat = ODataFormat.fromContentType(responseFormat);
+ ODataSerializer serializer = this.odata.createSerializer(oDataFormat);
+ SerializerResult serializerResult = serializer.entity(serviceMetadata, entityType, entity, options);
+ InputStream entityStream = serializerResult.getContent();
+
+ // 4. configure the response object
+ response.setContent(entityStream);
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
+ }
+
+ /*
+ * These processor methods are not handled in this tutorial
+ */
+
+ public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat,
+ ContentType responseFormat)
+ throws ODataApplicationException, DeserializerException, SerializerException {
+ throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+
+ public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat,
+ ContentType responseFormat)
+ throws ODataApplicationException, DeserializerException, SerializerException {
+ throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+
+ public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo)
+ throws ODataApplicationException {
+ throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/010d94f7/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java
new file mode 100755
index 0000000..64f7949
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java
@@ -0,0 +1,150 @@
+/*
+ * 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 myservice.mynamespace.service;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Locale;
+
+import myservice.mynamespace.data.Storage;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.deserializer.DeserializerException;
+import org.apache.olingo.server.api.processor.PrimitiveProcessor;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.serializer.SerializerResult;
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.uri.UriParameter;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+import org.apache.olingo.server.api.uri.UriResourceProperty;
+
+public class DemoPrimitiveProcessor implements PrimitiveProcessor {
+
+ private OData odata;
+ private Storage storage;
+
+ public DemoPrimitiveProcessor(Storage storage) {
+ this.storage = storage;
+ }
+
+ public void init(OData odata, ServiceMetadata serviceMetadata) {
+ this.odata = odata;
+
+ }
+
+ /*
+ * In our example, the URL would be: http://localhost:8080/DemoService/DemoService.svc/Products(1)/Name
+ * and the response:
+ * {
+ * @odata.context: "$metadata#Products/Name",
+ * value: "Notebook Basic 15"
+ * }
+ * */
+ public void readPrimitive(ODataRequest request, ODataResponse response,
+ UriInfo uriInfo, ContentType responseFormat)
+ throws ODataApplicationException, SerializerException {
+
+ // 1. Retrieve info from URI
+ // 1.1. retrieve the info about the requested entity set
+ List<UriResource> resourceParts = uriInfo.getUriResourceParts();
+ // Note: only in our example we can rely that the first segment is the EntitySet
+ UriResourceEntitySet uriEntityset = (UriResourceEntitySet) resourceParts.get(0);
+ EdmEntitySet edmEntitySet = uriEntityset.getEntitySet();
+ // the key for the entity
+ List<UriParameter> keyPredicates = uriEntityset.getKeyPredicates();
+
+ // 1.2. retrieve the requested (Edm) property
+ // the last segment is the Property
+ UriResourceProperty uriProperty = (UriResourceProperty)resourceParts.get(resourceParts.size() -1);
+ EdmProperty edmProperty = uriProperty.getProperty();
+ String edmPropertyName = edmProperty.getName();
+ // in our example, we know we have only primitive types in our model
+ EdmPrimitiveType edmPropertyType = (EdmPrimitiveType) edmProperty.getType();
+
+
+ // 2. retrieve data from backend
+ // 2.1. retrieve the entity data, for which the property has to be read
+ Entity entity = storage.readEntityData(edmEntitySet, keyPredicates);
+ if (entity == null) { // Bad request
+ throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
+ }
+
+ // 2.2. retrieve the property data from the entity
+ Property property = entity.getProperty(edmPropertyName);
+ if (property == null) {
+ throw new ODataApplicationException("Property not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
+ }
+
+ // 3. serialize
+ Object value = property.getValue();
+ if (value != null) {
+ // 3.1. configure the serializer
+ ODataFormat format = ODataFormat.fromContentType(responseFormat);
+ ODataSerializer serializer = odata.createSerializer(format);
+
+ ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).navOrPropertyPath(edmPropertyName).build();
+ PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextUrl).build();
+ // 3.2. serialize
+ SerializerResult serializerResult = serializer.primitive(edmPropertyType, property, options);
+ InputStream propertyStream = serializerResult.getContent();
+
+ //4. configure the response object
+ response.setContent(propertyStream);
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
+ } else {
+ // in case there's no value for the property, we can skip the serialization
+ response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+ }
+ }
+
+
+
+ /*
+ * These processor methods are not handled in this tutorial
+ * */
+
+ public void updatePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo,
+ ContentType requestFormat, ContentType responseFormat)
+ throws ODataApplicationException, DeserializerException, SerializerException {
+ throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+
+ public void deletePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo)
+ throws ODataApplicationException {
+ throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/010d94f7/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/util/Util.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/util/Util.java b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/util/Util.java
new file mode 100755
index 0000000..c21d352
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/util/Util.java
@@ -0,0 +1,105 @@
+/*
+ * 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 myservice.mynamespace.util;
+
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntityCollection;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmType;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.uri.UriInfoResource;
+import org.apache.olingo.server.api.uri.UriParameter;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+
+public class Util {
+
+ public static Entity findEntity(EdmEntityType edmEntityType, EntityCollection entitySet,
+ List<UriParameter> keyParams) throws ODataApplicationException {
+
+ List<Entity> entityList = entitySet.getEntities();
+
+ // loop over all entities in order to find that one that matches all keys in request
+ // e.g. contacts(ContactID=1, CompanyID=1)
+ for (Entity entity: entityList) {
+ boolean foundEntity = entityMatchesAllKeys(edmEntityType, entity, keyParams);
+ if (foundEntity) {
+ return entity;
+ }
+ }
+
+ return null;
+ }
+
+ public static boolean entityMatchesAllKeys(EdmEntityType edmEntityType, Entity entity, List<UriParameter> keyParams)
+ throws ODataApplicationException {
+
+ // loop over all keys
+ for (final UriParameter key : keyParams) {
+ // key
+ String keyName = key.getName();
+ String keyText = key.getText();
+
+ // Edm: we need this info for the comparison below
+ EdmProperty edmKeyProperty = (EdmProperty) edmEntityType.getProperty(keyName);
+ Boolean isNullable = edmKeyProperty.isNullable();
+ Integer maxLength = edmKeyProperty.getMaxLength();
+ Integer precision = edmKeyProperty.getPrecision();
+ Boolean isUnicode = edmKeyProperty.isUnicode();
+ Integer scale = edmKeyProperty.getScale();
+ // get the EdmType in order to compare
+ EdmType edmType = edmKeyProperty.getType();
+ EdmPrimitiveType edmPrimitiveType = (EdmPrimitiveType) edmType;
+
+ // Runtime data: the value of the current entity
+ // don't need to check for null, this is done in olingo library
+ Object valueObject = entity.getProperty(keyName).getValue();
+
+ // now need to compare the valueObject with the keyText String
+ // this is done using the type.valueToString
+ String valueAsString;
+ try {
+ valueAsString = edmPrimitiveType.valueToString(valueObject, isNullable, maxLength, precision, scale, isUnicode);
+ } catch (EdmPrimitiveTypeException e) {
+ throw new ODataApplicationException("Failed to retrieve String value", HttpStatusCode.INTERNAL_SERVER_ERROR
+ .getStatusCode(), Locale.ENGLISH, e);
+ }
+
+ if (valueAsString == null) {
+ return false;
+ }
+
+ boolean matches = valueAsString.equals(keyText);
+ if (!matches) {
+ // if any of the key properties is not found in the entity, we don't need to search further
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/010d94f7/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/web/DemoServlet.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/web/DemoServlet.java b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/web/DemoServlet.java
new file mode 100755
index 0000000..fe5cdbb
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/web/DemoServlet.java
@@ -0,0 +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 myservice.mynamespace.web;
+
+import java.io.IOException;
+import java.lang.Override;import java.lang.RuntimeException;import java.util.ArrayList;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import myservice.mynamespace.data.Storage;
+import myservice.mynamespace.service.DemoEdmProvider;
+import myservice.mynamespace.service.DemoEntityCollectionProcessor;
+import myservice.mynamespace.service.DemoEntityProcessor;
+import myservice.mynamespace.service.DemoPrimitiveProcessor;
+
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataHttpHandler;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.edmx.EdmxReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DemoServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+ private static final Logger LOG = LoggerFactory.getLogger(DemoServlet.class);
+
+
+ @Override
+ protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ try {
+ HttpSession session = req.getSession(true);
+ Storage storage = (Storage) session.getAttribute(Storage.class.getName());
+ if (storage == null) {
+ storage = new Storage();
+ session.setAttribute(Storage.class.getName(), storage);
+ }
+
+ // create odata handler and configure it with EdmProvider and Processor
+ OData odata = OData.newInstance();
+ ServiceMetadata edm = odata.createServiceMetadata(new DemoEdmProvider(), new ArrayList<EdmxReference>());
+ ODataHttpHandler handler = odata.createHandler(edm);
+ handler.register(new DemoEntityCollectionProcessor(storage));
+ handler.register(new DemoEntityProcessor(storage));
+ handler.register(new DemoPrimitiveProcessor(storage));
+
+ // let the handler do the work
+ handler.process(req, resp);
+ } catch (RuntimeException e) {
+ LOG.error("Server Error occurred in ExampleServlet", e);
+ throw new ServletException(e);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/010d94f7/samples/tutorials/p5_queryoptions/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/webapp/WEB-INF/web.xml b/samples/tutorials/p5_queryoptions/src/main/webapp/WEB-INF/web.xml
new file mode 100755
index 0000000..21de52a
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,40 @@
+<?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.
+-->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ id="WebApp_ID" version="2.5">
+
+ <!-- Register the HttpServlet implementation -->
+ <servlet>
+ <servlet-name>DemoServlet</servlet-name>
+ <servlet-class>myservice.mynamespace.web.DemoServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <!--
+ Our OData service can be invoked at
+ http://localhost:8080/DemoService/DemoService.svc
+ -->
+ <servlet-mapping>
+ <servlet-name>DemoServlet</servlet-name>
+ <url-pattern>/DemoService.svc/*</url-pattern>
+ </servlet-mapping>
+</web-app>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/010d94f7/samples/tutorials/p5_queryoptions/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/webapp/index.jsp b/samples/tutorials/p5_queryoptions/src/main/webapp/index.jsp
new file mode 100755
index 0000000..7ffb4ba
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions/src/main/webapp/index.jsp
@@ -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.
+
+-->
+<html>
+<body>
+<h2>Hello World!</h2>
+<a href="DemoService.svc/">OData Olingo V4 Demo Service</a>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/010d94f7/samples/tutorials/pom.xml
----------------------------------------------------------------------
diff --git a/samples/tutorials/pom.xml b/samples/tutorials/pom.xml
index 915fbb5..111e200 100644
--- a/samples/tutorials/pom.xml
+++ b/samples/tutorials/pom.xml
@@ -39,6 +39,7 @@
<module>p2_readep</module>
<module>p3_write</module>
<module>p4_navigation</module>
+ <module>p5_queryoptions</module>
</modules>
<build>
[06/18] olingo-odata4 git commit: [OLINGO-731] Added html as debug
output and refactored structure
Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabBody.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabBody.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabBody.java
new file mode 100644
index 0000000..43e9ba6
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabBody.java
@@ -0,0 +1,149 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.regex.Pattern;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.debug.DebugSupport;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+/**
+ * Response body debug information.
+ */
+public class DebugTabBody implements DebugTab {
+
+ private static enum ResponseContent {
+ JSON, XML, TEXT, IMAGE
+ };
+
+ private final ODataResponse response;
+ private final ResponseContent responseContent;
+
+ private final String serviceRoot;
+
+// private final boolean isXml;
+// private final boolean isJson;
+// private final boolean isText;
+// private final boolean isImage;
+
+ public DebugTabBody(final ODataResponse response, final String serviceRoot) {
+ this.response = response;
+ this.serviceRoot = serviceRoot;
+ final String contentType = response.getHeaders().get(HttpHeader.CONTENT_TYPE);
+ // TODO: Differentiate better
+ if (contentType != null) {
+ responseContent = ResponseContent.JSON;
+ } else {
+ responseContent = ResponseContent.TEXT;
+ }
+// isXml = contentType.contains("xml");
+// isJson = !isXml && contentType.startsWith(HttpContentType.APPLICATION_JSON);
+// isText = isXml || isJson || contentType.startsWith("text/")
+// || contentType.startsWith(HttpContentType.APPLICATION_HTTP)
+// || contentType.startsWith(HttpContentType.MULTIPART_MIXED);
+// isImage = !isText && contentType.startsWith("image/");
+ }
+
+ @Override
+ public String getName() {
+ return "Body";
+ }
+
+//
+ @Override
+ public void appendJson(final JsonGenerator gen) throws IOException {
+ if (response.getContent() == null) {
+ gen.writeNull();
+ } else {
+ gen.writeString(getContentString());
+ }
+ }
+
+ private String getContentString() {
+ try {
+ String contentString;
+ switch (responseContent) {
+ case IMAGE:
+ // TODO: DecodeString as base 64
+ contentString = "Currently not supported";
+ break;
+ case JSON:
+ case XML:
+ case TEXT:
+ default:
+ // TODO: Remove IOUtils from core dependency
+ contentString = IOUtils.toString(response.getContent(), "UTF-8");
+ break;
+ }
+ return contentString;
+ } catch (IOException e) {
+ return "Could not parse Body for Debug Output";
+ }
+ }
+
+ @Override
+ public void appendHtml(final Writer writer) throws IOException {
+
+ final String body = response.getContent() == null ? "ODataLibrary: null body." : getContentString();
+ switch (responseContent) {
+ case XML:
+ writer.append("<pre class=\"code").append("xml").append("\">\n");
+ writer.append(addLinks(DebugResponseHelperImpl.escapeHtml(body)));
+ writer.append("</pre>\n");
+ break;
+ case JSON:
+ writer.append("<pre class=\"code").append("json").append("\">\n");
+ writer.append(addLinks(DebugResponseHelperImpl.escapeHtml(body)));
+ writer.append("</pre>\n");
+ break;
+ case IMAGE:
+ // Make header query case insensitive
+ writer.append("<img src=\"data:").append(response.getHeaders().get(HttpHeader.CONTENT_TYPE)).append(";base64,")
+ .append(body)
+ .append("\" />\n");
+ break;
+ case TEXT:
+ default:
+ writer.append("<pre class=\"code").append("").append("\">\n");
+ writer.append(DebugResponseHelperImpl.escapeHtml(body));
+ writer.append("</pre>\n");
+ break;
+ }
+ }
+
+ private String addLinks(final String source) {
+ final String debugOption = DebugSupport.ODATA_DEBUG_QUERY_PARAMETER + "=" + DebugSupport.ODATA_DEBUG_HTML;
+ final String urlPattern = "("
+ + (responseContent == ResponseContent.XML ?
+ "(?:href|src|base)=" : "\"(?:uri|media_src|edit_media|__next)\":\\p{Space}*")
+ + "\")(.+?)\"";
+ return (responseContent == ResponseContent.XML ?
+ source.replaceAll("(xmlns(?::\\p{Alnum}+)?=\")(.+?)\"", "$1<span class=\"ns\">$2</span>\"") : source)
+ .replaceAll(urlPattern, "$1<a href=\"" + serviceRoot + "$2?" + debugOption + "\">$2</a>\"")
+ .replaceAll("(<a href=\"" + Pattern.quote(serviceRoot) + ')' + Pattern.quote(serviceRoot), "$1")
+ .replaceAll("<a href=\"(.+?)\\?(.+?)\\?" + debugOption, "<a href=\"$1?$2&" + debugOption)
+ .replaceAll("&amp;", "&");
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabException.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabException.java
new file mode 100644
index 0000000..6bc69e4
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabException.java
@@ -0,0 +1,136 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.olingo.server.api.ODataLibraryException;
+import org.apache.olingo.server.api.ODataLibraryException.ODataErrorMessage;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+/**
+ * Exception debug information.
+ */
+public class DebugTabException implements DebugTab {
+
+ private final Exception exception;
+
+ public DebugTabException(final Exception exception) {
+ this.exception = exception;
+ }
+
+ @Override
+ public String getName() {
+ return "Stacktrace";
+ }
+
+ @Override
+ public void appendJson(final JsonGenerator gen) throws IOException {
+ gen.writeStartObject();
+ gen.writeFieldName("exceptions");
+ gen.writeStartArray();
+ Throwable throwable = exception;
+ while (throwable != null) {
+ gen.writeStartObject();
+ gen.writeStringField("class", throwable.getClass().getCanonicalName());
+ gen.writeStringField("message", getMessageText(throwable));
+ gen.writeFieldName("invocation");
+ appendJsonStackTraceElement(gen, throwable.getStackTrace()[0]);
+ gen.writeEndObject();
+
+ // Get next exception in the cause list
+ throwable = throwable.getCause();
+ }
+ gen.writeEndArray();
+
+ gen.writeFieldName("stacktrace");
+ gen.writeStartArray();
+ for (final StackTraceElement stackTraceElement : exception.getStackTrace()) {
+ appendJsonStackTraceElement(gen, stackTraceElement);
+ }
+ gen.writeEndArray();
+
+ gen.writeEndObject();
+ }
+
+ private String getMessageText(final Throwable throwable) {
+ String message;
+ if (throwable instanceof ODataLibraryException) {
+ ODataLibraryException ex = (ODataLibraryException) throwable;
+ // We use the default locale
+ ODataErrorMessage translatedMessage = ex.getTranslatedMessage(null);
+ // We provide the best message we can
+ message = translatedMessage.getMessage() == null ? ex.getMessage() : translatedMessage.getMessage();
+ } else {
+ message = throwable.getMessage();
+ }
+ return message;
+ }
+
+ private void appendJsonStackTraceElement(final JsonGenerator gen, final StackTraceElement element)
+ throws IOException {
+ gen.writeStartObject();
+ gen.writeStringField("class", element.getClassName());
+ gen.writeStringField("method", element.getMethodName());
+ gen.writeStringField("line", Integer.toString(element.getLineNumber()));
+ gen.writeEndObject();
+ }
+
+ @Override
+ public void appendHtml(final Writer writer) throws IOException {
+ appendException(exception, writer);
+ writer.append("<h2>Stacktrace</h2>\n");
+ int count = 0;
+ for (final StackTraceElement stackTraceElement : exception.getStackTrace()) {
+ appendStackTraceElement(stackTraceElement, ++count == 1, count == exception.getStackTrace().length, writer);
+ }
+ }
+
+ private void appendException(final Throwable throwable, final Writer writer) throws IOException {
+ if (throwable.getCause() != null) {
+ appendException(throwable.getCause(), writer);
+ }
+ final StackTraceElement details = throwable.getStackTrace()[0];
+ writer.append("<h2>").append(throwable.getClass().getCanonicalName()).append("</h2>\n")
+ .append("<p>")
+ .append(DebugResponseHelperImpl.escapeHtml(getMessageText(throwable)))
+ .append("</p>\n");
+ appendStackTraceElement(details, true, true, writer);
+ }
+
+ private void appendStackTraceElement(final StackTraceElement stackTraceElement,
+ final boolean isFirst, final boolean isLast, final Writer writer) throws IOException {
+ if (isFirst) {
+ writer.append("<table>\n<thead>\n")
+ .append("<tr>\n<th class=\"name\">Class</th>\n")
+ .append("<th class=\"name\">Method</th>\n")
+ .append("<th class=\"value\">Line number in class</th>\n</tr>\n")
+ .append("</thead>\n<tbody>\n");
+ }
+ writer.append("<tr>\n<td class=\"name\">").append(stackTraceElement.getClassName()).append("</td>\n")
+ .append("<td class=\"name\">").append(stackTraceElement.getMethodName()).append("</td>\n")
+ .append("<td class=\"value\">").append(Integer.toString(stackTraceElement.getLineNumber()))
+ .append("</td>\n</tr>\n");
+ if (isLast) {
+ writer.append("</tbody>\n</table>\n");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabRequest.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabRequest.java
new file mode 100644
index 0000000..8eba537
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabRequest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.server.api.ODataRequest;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+/**
+ * Request debug information.
+ */
+public class DebugTabRequest implements DebugTab {
+
+ private final String method;
+ private final String uri;
+ private final String protocol;
+ private final Map<String, String> headers;
+
+ public DebugTabRequest(ODataRequest request) {
+ method = request.getMethod() == null ? "unkown" : request.getMethod().toString();
+ uri = request.getRawRequestUri() == null ? "unkown" : request.getRawRequestUri();
+ protocol = request.getProtocol() == null ? "unkown" : request.getProtocol();
+ // TODO: Should we really wrap the headers here or keep the original structure?
+ headers = wrapHeaders(request.getAllHeaders());
+ }
+
+ private Map<String, String> wrapHeaders(Map<String, List<String>> allHeaders) {
+ Map<String, String> localHeaders = new LinkedHashMap<String, String>();
+ for (Map.Entry<String, List<String>> entry : allHeaders.entrySet()) {
+ String value = null;
+ if (entry.getValue() != null) {
+ value = "";
+ boolean first = true;
+ for (String valuePart : entry.getValue()) {
+ if (!first) {
+ value = value + ", ";
+ }
+ value = value + valuePart;
+ }
+ }
+ localHeaders.put(entry.getKey(), value);
+ }
+ return localHeaders;
+ }
+
+ @Override
+ public void appendHtml(final Writer writer) throws IOException {
+ writer.append("<h2>Request Method</h2>\n")
+ .append("<p>").append(method).append("</p>\n")
+ .append("<h2>Request URI</h2>\n")
+ .append("<p>").append(DebugResponseHelperImpl.escapeHtml(uri.toString())).append("</p>\n")
+ .append("<h2>Request Protocol</h2>\n")
+ .append("<p>").append(protocol).append("</p>\n");
+ writer.append("<h2>Request Headers</h2>\n");
+ DebugResponseHelperImpl.appendHtmlTable(writer, headers);
+
+// .append("<table>\n<thead>\n")
+// .append("<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n")
+// .append("</thead>\n<tbody>\n");
+// for (final String name : headers.keySet()) {
+// for (final String value : headers.get(name)) {
+// if (value != null) {
+// writer.append("<tr><td class=\"name\">").append(name).append("</td>")
+// .append("<td class=\"value\">").append(DebugResponseHelperImpl.escapeHtml(value))
+// .append("</td></tr>\n");
+// }
+// }
+// }
+// writer.append("</tbody>\n</table>\n");
+ }
+
+ @Override
+ public String getName() {
+ return "Request";
+ }
+
+ @Override
+ public void appendJson(JsonGenerator gen) throws IOException {
+ gen.writeStartObject();
+ gen.writeStringField("method", method);
+
+ gen.writeStringField("uri", uri);
+
+ gen.writeStringField("protocol", protocol);
+
+ if (!headers.isEmpty()) {
+ gen.writeFieldName("headers");
+ DebugResponseHelperImpl.appendJsonTable(gen, headers);
+ }
+
+ gen.writeEndObject();
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabResponse.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabResponse.java
new file mode 100644
index 0000000..5cb153c
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabResponse.java
@@ -0,0 +1,89 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Map;
+
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.ODataResponse;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+/**
+ * Response debug information.
+ */
+public class DebugTabResponse implements DebugTab {
+
+ private final ODataResponse response;
+ private final String serviceRoot;
+ private final HttpStatusCode status;
+ private final Map<String, String> headers;
+
+ public DebugTabResponse(final ODataResponse applicationResponse, final String serviceRoot) {
+ this.response = applicationResponse;
+ this.serviceRoot = serviceRoot;
+ status = HttpStatusCode.fromStatusCode(response.getStatusCode());
+ headers = response.getHeaders();
+ }
+
+ @Override
+ public String getName() {
+ return "Response";
+ }
+
+ @Override
+ public void appendJson(final JsonGenerator gen) throws IOException {
+ gen.writeStartObject();
+
+ if (status != null) {
+ gen.writeFieldName("status");
+ gen.writeStartObject();
+ gen.writeStringField("code", Integer.toString(status.getStatusCode()));
+ gen.writeStringField("info", status.getInfo());
+ gen.writeEndObject();
+ }
+
+ if (headers != null && !headers.isEmpty()) {
+ gen.writeFieldName("headers");
+ DebugResponseHelperImpl.appendJsonTable(gen, headers);
+ }
+
+ gen.writeFieldName("body");
+ new DebugTabBody(response, serviceRoot).appendJson(gen);
+
+ gen.writeEndObject();
+ }
+
+ @Override
+ public void appendHtml(final Writer writer) throws IOException {
+ writer.append("<h2>Status Code</h2>\n")
+ .append("<p>").append(Integer.toString(status.getStatusCode())).append(' ')
+ .append(status.getInfo()).append("</p>\n")
+ .append("<h2>Response Headers</h2>\n");
+ DebugResponseHelperImpl.appendHtmlTable(writer, headers);
+ writer.append("<h2>Response Body</h2>\n");
+ if (response.getContent() != null) {
+ new DebugTabBody(response, serviceRoot).appendHtml(writer);
+ } else {
+ writer.append("<p>ODataLibrary: no response body</p>");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabRuntime.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabRuntime.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabRuntime.java
new file mode 100644
index 0000000..312b4cd
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabRuntime.java
@@ -0,0 +1,181 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.olingo.server.api.debug.RuntimeMeasurement;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+/**
+ * Runtime debug information.
+ */
+public class DebugTabRuntime implements DebugTab {
+
+ private final RuntimeNode rootNode;
+
+ public DebugTabRuntime(List<RuntimeMeasurement> runtimeInformation) {
+ rootNode = new RuntimeNode();
+ for (final RuntimeMeasurement runtimeMeasurement : runtimeInformation) {
+ rootNode.add(runtimeMeasurement);
+ }
+ rootNode.combineRuntimeMeasurements();
+ }
+
+ @Override
+ public String getName() {
+ return "Runtime";
+ }
+
+ @Override
+ public void appendJson(JsonGenerator gen) throws IOException {
+ appendJsonChildren(gen, rootNode);
+ }
+
+ private void appendJsonChildren(JsonGenerator gen, RuntimeNode node) throws IOException {
+ gen.writeStartArray();
+ for (RuntimeNode child : node.children) {
+ appendJsonNode(gen, child);
+ }
+ gen.writeEndArray();
+ }
+
+ private void appendJsonNode(JsonGenerator gen, RuntimeNode node) throws IOException {
+ gen.writeStartObject();
+ gen.writeStringField("class", node.className);
+ gen.writeStringField("method ", node.methodName);
+
+ if (node.timeStopped == 0) {
+ gen.writeNullField("duration");
+ } else {
+ gen.writeStringField("duration", Long.toString((node.timeStopped - node.timeStarted) / 1000));
+ gen.writeStringField("unit", "µs");
+ }
+
+ if (!node.children.isEmpty()) {
+ gen.writeFieldName("children");
+ appendJsonChildren(gen, node);
+ }
+
+ gen.writeEndObject();
+ }
+
+ @Override
+ public void appendHtml(final Writer writer) throws IOException {
+ appendRuntimeNode(rootNode, "", true, writer);
+ }
+
+ private void appendRuntimeNode(final RuntimeNode node, final String draw, final boolean isLast, final Writer writer)
+ throws IOException {
+ if (node.className != null) {
+ writer.append("<li>")
+ .append("<span class=\"code\">")
+ .append("<span class=\"draw\">").append(draw)
+ .append(isLast ? "└" : "├").append("─ </span>")
+ .append("<span class=\"class\">").append(node.className).append("</span>.")
+ .append("<span class=\"method\">").append(node.methodName).append("(…)")
+ .append("</span></span>");
+ long time = node.timeStopped == 0 ? 0 : (node.timeStopped - node.timeStarted) / 1000;
+ writer.append("<span class=\"").append(time == 0 ? "null" : "numeric")
+ .append("\" title=\"").append(time == 0 ? "Stop time missing" : "Gross duration")
+ .append("\">").append(time == 0 ? "unfinished" : Long.toString(time) + " µs")
+ .append("</span>\n");
+ }
+ if (!node.children.isEmpty()) {
+ writer.append("<ol class=\"tree\">\n");
+ for (final RuntimeNode childNode : node.children) {
+ appendRuntimeNode(childNode,
+ node.className == null ? draw : draw + (isLast ? " " : "│") + " ",
+ node.children.indexOf(childNode) == node.children.size() - 1,
+ writer);
+ }
+ writer.append("</ol>\n");
+ }
+ if (node.className != null) {
+ writer.append("</li>\n");
+ }
+ }
+
+ private class RuntimeNode {
+
+ protected String className;
+ protected String methodName;
+ protected long timeStarted;
+ protected long timeStopped;
+ protected List<RuntimeNode> children = new ArrayList<RuntimeNode>();
+
+ protected RuntimeNode() {
+ timeStarted = 0;
+ timeStopped = Long.MAX_VALUE;
+ }
+
+ private RuntimeNode(final RuntimeMeasurement runtimeMeasurement) {
+ className = runtimeMeasurement.getClassName();
+ methodName = runtimeMeasurement.getMethodName();
+ timeStarted = runtimeMeasurement.getTimeStarted();
+ timeStopped = runtimeMeasurement.getTimeStopped();
+ }
+
+ protected boolean add(final RuntimeMeasurement runtimeMeasurement) {
+ if (timeStarted <= runtimeMeasurement.getTimeStarted()
+ && timeStopped != 0 && timeStopped >= runtimeMeasurement.getTimeStopped()) {
+ for (RuntimeNode candidate : children) {
+ if (candidate.add(runtimeMeasurement)) {
+ return true;
+ }
+ }
+ children.add(new RuntimeNode(runtimeMeasurement));
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Combines runtime measurements with identical class names and method
+ * names into one measurement, assuming that they originate from a loop
+ * or a similar construct where a summary measurement has been intended.
+ */
+ protected void combineRuntimeMeasurements() {
+ RuntimeNode preceding = null;
+ for (Iterator<RuntimeNode> iterator = children.iterator(); iterator.hasNext();) {
+ final RuntimeNode child = iterator.next();
+ if (preceding != null
+ && preceding.timeStopped != 0 && child.timeStopped != 0
+ && preceding.timeStopped <= child.timeStarted
+ && preceding.children.isEmpty() && child.children.isEmpty()
+ && preceding.methodName.equals(child.methodName)
+ && preceding.className.equals(child.className)) {
+ preceding.timeStarted = child.timeStarted - (preceding.timeStopped - preceding.timeStarted);
+ preceding.timeStopped = child.timeStopped;
+
+ iterator.remove();
+ } else {
+ preceding = child;
+ child.combineRuntimeMeasurements();
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabServer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabServer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabServer.java
new file mode 100644
index 0000000..4eb95ba
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabServer.java
@@ -0,0 +1,57 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+/**
+ * Server debug information.
+ */
+public class DebugTabServer implements DebugTab {
+
+ private final Map<String, String> serverEnvironmentVaribles;
+
+ public DebugTabServer(Map<String, String> serverEnvironmentVaribles) {
+ this.serverEnvironmentVaribles = serverEnvironmentVaribles;
+ }
+
+ @Override
+ public String getName() {
+ return "Environment";
+ }
+
+ @Override
+ public void appendJson(JsonGenerator gen) throws IOException {
+ DebugResponseHelperImpl.appendJsonTable(gen, serverEnvironmentVaribles);
+ }
+
+ @Override
+ public void appendHtml(Writer writer) throws IOException {
+ final Package pack = DebugResponseHelperImpl.class.getPackage();
+ writer.append("<h2>Library Version</h2>\n")
+ .append("<p>").append(pack.getImplementationTitle())
+ .append(" Version ").append(pack.getImplementationVersion()).append("</p>\n")
+ .append("<h2>Server Environment</h2>\n");
+ DebugResponseHelperImpl.appendHtmlTable(writer, serverEnvironmentVaribles);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabUri.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabUri.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabUri.java
new file mode 100644
index 0000000..5c50c0f
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTabUri.java
@@ -0,0 +1,232 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.olingo.server.api.uri.UriInfo;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+
+/**
+ * URI parser debug information.
+ */
+public class DebugTabUri implements DebugTab {
+
+ private UriInfo uriInfo;
+
+ public DebugTabUri(UriInfo uriInfo) {
+ this.uriInfo = uriInfo;
+ }
+
+ @Override
+ public String getName() {
+ return "URI";
+ }
+
+ @Override
+ public void appendJson(JsonGenerator jsonGenerator) throws IOException {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void appendHtml(Writer writer) throws IOException {
+ // TODO Auto-generated method stub
+
+ }
+
+// private final UriInfo uriInfo;
+// private final FilterExpression filter;
+// private final OrderByExpression orderBy;
+// private final ExpandSelectTreeNodeImpl expandSelectTree;
+// private final ExpressionParserException exception;
+//
+// public DebugInfoUri(final UriInfo uriInfo, final ExpressionParserException exception) {
+// this.uriInfo = uriInfo;
+// filter = uriInfo == null ? null : uriInfo.getFilter();
+// orderBy = uriInfo == null ? null : uriInfo.getOrderBy();
+// expandSelectTree = uriInfo == null ? null : getExpandSelect();
+// this.exception = exception;
+// }
+//
+// private ExpandSelectTreeNodeImpl getExpandSelect() {
+// try {
+// return uriInfo.getExpand().isEmpty() && uriInfo.getSelect().isEmpty() ? null :
+// new ExpandSelectTreeCreator(uriInfo.getSelect(), uriInfo.getExpand()).create();
+// } catch (final EdmException e) {
+// return null;
+// }
+// }
+// @Override
+// public void appendJson(final JsonStreamWriter jsonStreamWriter) throws IOException {
+// jsonStreamWriter.beginObject();
+//
+// if (exception != null && exception.getFilterTree() != null) {
+// jsonStreamWriter.name("error")
+// .beginObject()
+// .namedStringValue("expression", exception.getFilterTree().getUriLiteral())
+// .endObject();
+// if (filter != null || orderBy != null || expandSelectTree != null) {
+// jsonStreamWriter.separator();
+// }
+// }
+//
+// if (filter != null) {
+// String filterString;
+// try {
+// filterString = (String) filter.accept(new JsonVisitor());
+// } catch (final ExceptionVisitExpression e) {
+// filterString = null;
+// } catch (final ODataApplicationException e) {
+// filterString = null;
+// }
+// jsonStreamWriter.name("filter").unquotedValue(filterString);
+// if (orderBy != null || expandSelectTree != null) {
+// jsonStreamWriter.separator();
+// }
+// }
+//
+// if (orderBy != null) {
+// String orderByString;
+// try {
+// orderByString = (String) orderBy.accept(new JsonVisitor());
+// } catch (final ExceptionVisitExpression e) {
+// orderByString = null;
+// } catch (final ODataApplicationException e) {
+// orderByString = null;
+// }
+// jsonStreamWriter.name("orderby").unquotedValue(orderByString);
+// if (expandSelectTree != null) {
+// jsonStreamWriter.separator();
+// }
+// }
+//
+// if (expandSelectTree != null) {
+// jsonStreamWriter.name("expandSelect").unquotedValue(expandSelectTree.toJsonString());
+// }
+//
+// jsonStreamWriter.endObject();
+// }
+//
+// @Override
+// public void appendHtml(final Writer writer) throws IOException {
+// if (exception != null && exception.getFilterTree() != null) {
+// writer.append("<h2>Expression Information</h2>\n")
+// .append("<pre class=\"code\">").append(exception.getFilterTree().getUriLiteral())
+// .append("</pre>\n");
+// // TODO: filter error position, filter tokens, filter tree
+// }
+// if (filter != null) {
+// writer.append("<h2>Filter</h2>\n")
+// .append("<ul class=\"expr\"><li>");
+// appendExpression(filter.getExpression(), writer);
+// writer.append("</li></ul>\n");
+// }
+// if (orderBy != null) {
+// writer.append("<h2>Orderby</h2>\n")
+// .append(orderBy.getOrdersCount() == 1 ? "<ul" : "<ol").append(" class=\"expr\">\n");
+// for (final OrderExpression order : orderBy.getOrders()) {
+// writer.append("<li>");
+// appendExpression(order.getExpression(), writer);
+// final ExpressionKind kind = order.getExpression().getKind();
+// if (kind == ExpressionKind.PROPERTY || kind == ExpressionKind.LITERAL) {
+// writer.append("<br />");
+// }
+// writer.append("<span class=\"order\">")
+// .append(order.getSortOrder().toString())
+// .append("</span></li>\n");
+// }
+// writer.append(orderBy.getOrdersCount() == 1 ? "</ul" : "</ol").append(">\n");
+// }
+// if (expandSelectTree != null) {
+// writer.append("<h2>Expand/Select</h2>\n");
+// appendExpandSelect(expandSelectTree, writer);
+// }
+// }
+//
+// private void appendExpression(final CommonExpression expression, final Writer writer) throws IOException {
+// final ExpressionKind kind = expression.getKind();
+// writer.append("<span class=\"kind\">")
+// .append(kind.toString())
+// .append("</span> <span class=\"literal\">")
+// .append(kind == ExpressionKind.MEMBER ? ((MemberExpression) expression).getProperty().getUriLiteral() :
+// expression.getUriLiteral())
+// .append("</span>, type <span class=\"type\">")
+// .append(expression.getEdmType().toString())
+// .append("</span>");
+// if (kind == ExpressionKind.UNARY) {
+// writer.append("<ul class=\"expr\"><li>");
+// appendExpression(((UnaryExpression) expression).getOperand(), writer);
+// writer.append("</li></ul>");
+// } else if (kind == ExpressionKind.BINARY) {
+// writer.append("<ol class=\"expr\"><li>");
+// appendExpression(((BinaryExpression) expression).getLeftOperand(), writer);
+// writer.append("</li><li>");
+// appendExpression(((BinaryExpression) expression).getRightOperand(), writer);
+// writer.append("</li></ol>");
+// } else if (kind == ExpressionKind.METHOD) {
+// final MethodExpression methodExpression = (MethodExpression) expression;
+// if (methodExpression.getParameterCount() > 0) {
+// writer.append("<ol class=\"expr\">");
+// for (final CommonExpression parameter : methodExpression.getParameters()) {
+// writer.append("<li>");
+// appendExpression(parameter, writer);
+// writer.append("</li>");
+// }
+// writer.append("</ol>");
+// }
+// } else if (kind == ExpressionKind.MEMBER) {
+// writer.append("<ul class=\"expr\"><li>");
+// appendExpression(((MemberExpression) expression).getPath(), writer);
+// writer.append("</li></ul>");
+// }
+// }
+//
+// private void appendExpandSelect(final ExpandSelectTreeNode expandSelect, final Writer writer) throws IOException {
+// writer.append("<ul class=\"expand\">\n")
+// .append("<li>");
+// if (expandSelect.isAll()) {
+// writer.append("all properties");
+// } else {
+// for (final EdmProperty property : expandSelect.getProperties()) {
+// try {
+// writer.append("property <span class=\"prop\">")
+// .append(property.getName())
+// .append("</span><br />");
+// } catch (final EdmException e) {}
+// }
+// }
+// writer.append("</li>\n");
+// if (!expandSelect.getLinks().isEmpty()) {
+// for (final String name : expandSelect.getLinks().keySet()) {
+// writer.append("<li>link <span class=\"link\">").append(name).append("</span>");
+// final ExpandSelectTreeNode link = expandSelect.getLinks().get(name);
+// if (link != null) {
+// writer.append('\n');
+// appendExpandSelect(link, writer);
+// }
+// writer.append("</li>\n");
+// }
+// }
+// writer.append("</ul>\n");
+// }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/ServerCoreDebugger.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/ServerCoreDebugger.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/ServerCoreDebugger.java
new file mode 100644
index 0000000..fcf611d
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/ServerCoreDebugger.java
@@ -0,0 +1,137 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.debug.DebugInformation;
+import org.apache.olingo.server.api.debug.DebugSupport;
+import org.apache.olingo.server.api.debug.RuntimeMeasurement;
+import org.apache.olingo.server.api.uri.UriInfo;
+
+public class ServerCoreDebugger {
+
+ private final List<RuntimeMeasurement> runtimeInformation = new ArrayList<RuntimeMeasurement>();
+ private final OData odata;
+
+ private boolean isDebugMode = false;
+ private DebugSupport debugSupport;
+ private String debugFormat;
+
+ public ServerCoreDebugger(OData odata) {
+ this.odata = odata;
+ }
+
+ public void resolveDebugMode(HttpServletRequest request) {
+ if (debugSupport != null) {
+ // Should we read the parameter from the servlet here and ignore multiple parameters?
+ debugFormat = request.getParameter(DebugSupport.ODATA_DEBUG_QUERY_PARAMETER);
+ if (debugFormat != null) {
+ debugSupport.init(odata);
+ isDebugMode = debugSupport.isUserAuthorized();
+ }
+ }
+ }
+
+ public ODataResponse createDebugResponse(final HttpServletRequest request, final Exception exception,
+ final ODataRequest odRequest, final ODataResponse odResponse, UriInfo uriInfo,
+ Map<String, String> serverEnvironmentVaribles) {
+ try {
+ DebugInformation debugInfo =
+ createDebugInformation(request, exception, odRequest, odResponse, uriInfo, serverEnvironmentVaribles);
+
+ return debugSupport.createDebugResponse(debugFormat, debugInfo);
+ } catch (Exception e) {
+ return createFailResponse();
+ }
+ }
+
+ private ODataResponse createFailResponse() {
+ ODataResponse odResponse = new ODataResponse();
+ odResponse.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
+ odResponse.setHeader(HttpHeader.CONTENT_TYPE, ContentType.TEXT_PLAIN.toContentTypeString());
+ InputStream content = new ByteArrayInputStream("ODataLibrary: Could not assemble debug response.".getBytes());
+ odResponse.setContent(content);
+ return null;
+ }
+
+ private DebugInformation createDebugInformation(final HttpServletRequest request, final Exception exception,
+ final ODataRequest odRequest, final ODataResponse odResponse, UriInfo uriInfo,
+ Map<String, String> serverEnvironmentVaribles) {
+ DebugInformation debugInfo = new DebugInformation();
+ debugInfo.setRequest(odRequest);
+ debugInfo.setApplicationResponse(odResponse);
+
+ debugInfo.setException(exception);
+
+ debugInfo.setServerEnvironmentVaribles(serverEnvironmentVaribles);
+
+ debugInfo.setUriInfo(uriInfo);
+
+ debugInfo.setRuntimeInformation(runtimeInformation);
+ return debugInfo;
+ }
+
+ public int startRuntimeMeasurement(final String className, final String methodName) {
+ if (isDebugMode) {
+ int handleId = runtimeInformation.size();
+
+ final RuntimeMeasurement measurement = new RuntimeMeasurement();
+ measurement.setTimeStarted(System.nanoTime());
+ measurement.setClassName(className);
+ measurement.setMethodName(methodName);
+
+ runtimeInformation.add(measurement);
+
+ return handleId;
+ } else {
+ return 0;
+ }
+ }
+
+ public void stopRuntimeMeasurement(final int handle) {
+ if (isDebugMode && handle < runtimeInformation.size()) {
+ long stopTime = System.nanoTime();
+ RuntimeMeasurement runtimeMeasurement = runtimeInformation.get(handle);
+ if (runtimeMeasurement != null) {
+ runtimeMeasurement.setTimeStopped(stopTime);
+ }
+ }
+ }
+
+ public void setDebugSupportProcessor(DebugSupport debugSupport) {
+ this.debugSupport = debugSupport;
+ }
+
+ public boolean isDebugMode() {
+ return isDebugMode;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java
index 0b5922c..8b74a88 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java
@@ -36,7 +36,6 @@ import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.debug.DefaultDebugSupport;
import org.apache.olingo.server.api.edmx.EdmxReference;
import org.apache.olingo.server.api.edmx.EdmxReferenceInclude;
-import org.apache.olingo.server.tecsvc.async.TechnicalAsyncService;
import org.apache.olingo.server.tecsvc.data.DataProvider;
import org.apache.olingo.server.tecsvc.processor.TechnicalActionProcessor;
import org.apache.olingo.server.tecsvc.processor.TechnicalBatchProcessor;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java
index 236c1b7..5b347d1 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java
@@ -6,9 +6,9 @@
* 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
@@ -77,6 +77,7 @@ import org.apache.olingo.server.api.processor.ReferenceCollectionProcessor;
import org.apache.olingo.server.api.processor.ReferenceProcessor;
import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.core.debug.ServerCoreDebugger;
import org.apache.olingo.server.tecsvc.provider.ContainerProvider;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.junit.Test;
@@ -233,7 +234,8 @@ public class ODataHandlerTest {
request.setMethod(HttpMethod.GET);
request.setRawODataPath("EdmException");
- final ODataResponse response = new ODataHandler(odata, serviceMetadata).process(request);
+ final ODataResponse response =
+ new ODataHandler(odata, serviceMetadata, new ServerCoreDebugger(odata)).process(request);
assertNotNull(response);
assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());
}
@@ -720,7 +722,7 @@ public class ODataHandlerTest {
final ServiceMetadata metadata = odata.createServiceMetadata(
new EdmTechProvider(), Collections.<EdmxReference> emptyList());
- ODataHandler handler = new ODataHandler(odata, metadata);
+ ODataHandler handler = new ODataHandler(odata, metadata, new ServerCoreDebugger(odata));
if (processor != null) {
handler.register(processor);
[16/18] olingo-odata4 git commit: Merge branch 'master' into olingo640
Posted by ch...@apache.org.
Merge branch 'master' into olingo640
Conflicts:
fit/src/test/java/org/apache/olingo/fit/tecsvc/client/NavigationITCase.java
lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/36659707
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/36659707
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/36659707
Branch: refs/heads/OLINGO-640
Commit: 366597070f08f7435eca9b2394c3f53612efd1d5
Parents: 5b99eb7 9558233
Author: Christian Amend <ch...@sap.com>
Authored: Tue Aug 4 14:38:01 2015 +0200
Committer: Christian Amend <ch...@sap.com>
Committed: Tue Aug 4 14:38:01 2015 +0200
----------------------------------------------------------------------
.../fit/tecsvc/client/AsyncSupportITCase.java | 104 +++++++
.../fit/tecsvc/client/NavigationITCase.java | 39 ++-
.../fit/tecsvc/http/BasicAsyncITCase.java | 238 ++++++++++++++++
.../apache/olingo/fit/util/StringHelper.java | 214 +++++++++++++++
fit/src/test/resources/basicBatchPost.batch | 33 +++
.../olingo/client/api/data/ServiceDocument.java | 4 +-
.../client/core/data/ServiceDocumentImpl.java | 53 +++-
.../core/data/ServiceDocumentItemImpl.java | 32 ++-
.../client/core/domain/ClientPropertyImpl.java | 39 ++-
.../client/core/domain/ClientValuableImpl.java | 27 +-
.../olingo/commons/api/data/ContextURL.java | 15 +-
.../commons/api/edm/FullQualifiedName.java | 32 ++-
.../apache/olingo/commons/api/edm/geo/SRID.java | 54 +++-
.../apache/olingo/server/api/ODataRequest.java | 22 +-
.../apache/olingo/server/api/ODataResponse.java | 2 +-
.../server/api/debug/DebugInformation.java | 118 ++++++++
.../server/api/debug/DebugResponseHelper.java | 6 +-
.../olingo/server/api/debug/DebugSupport.java | 7 +-
.../server/api/debug/DefaultDebugSupport.java | 13 +-
.../server/api/debug/RuntimeMeasurement.java | 106 +++++++
.../olingo/server/core/ServiceHandler.java | 15 +
.../core/legacy/ProcessorServiceHandler.java | 7 +
.../server/core/requests/DataRequest.java | 2 +-
.../olingo/server/example/TripPinHandler.java | 12 +
lib/server-core/pom.xml | 10 +-
.../apache/olingo/server/core/ODataHandler.java | 53 ++--
.../server/core/ODataHttpHandlerImpl.java | 68 +++--
.../apache/olingo/server/core/ODataImpl.java | 2 +-
.../core/debug/DebugResponseHelperImpl.java | 247 ++++++++++++++++-
.../olingo/server/core/debug/DebugTab.java | 50 ++++
.../olingo/server/core/debug/DebugTabBody.java | 154 +++++++++++
.../server/core/debug/DebugTabException.java | 136 +++++++++
.../server/core/debug/DebugTabRequest.java | 128 +++++++++
.../server/core/debug/DebugTabResponse.java | 99 +++++++
.../server/core/debug/DebugTabRuntime.java | 181 ++++++++++++
.../server/core/debug/DebugTabServer.java | 63 +++++
.../olingo/server/core/debug/DebugTabUri.java | 232 ++++++++++++++++
.../server/core/debug/ServerCoreDebugger.java | 142 ++++++++++
.../json/ODataJsonDeserializer.java | 275 +++++++++++--------
.../serializer/BatchResponseSerializer.java | 1 -
.../serializer/utils/ContextURLBuilder.java | 9 +
.../core/serializer/utils/ContextURLHelper.java | 30 ++
.../serializer/utils/ExpandSelectHelper.java | 11 +-
.../core/uri/parser/UriParseTreeVisitor.java | 29 +-
.../server/core/debug/AbstractDebugTabTest.java | 58 ++++
.../server/core/debug/DebugTabBodyTest.java | 37 +++
.../server/core/debug/DebugTabRequestTest.java | 155 +++++++++++
.../server/core/debug/DebugTabResponseTest.java | 79 ++++++
.../server/core/debug/DebugTabServerTest.java | 84 ++++++
.../core/debug/ServerCoreDebuggerTest.java | 121 ++++++++
lib/server-tecsvc/pom.xml | 1 -
.../olingo/server/tecsvc/TechnicalServlet.java | 1 -
.../processor/TechnicalBatchProcessor.java | 17 ++
.../processor/TechnicalEntityProcessor.java | 98 ++++---
lib/server-test/pom.xml | 1 -
.../olingo/server/core/ODataHandlerTest.java | 10 +-
.../json/ODataJsonDeserializerEntityTest.java | 50 ++++
.../serializer/utils/ContextURLHelperTest.java | 86 ++++++
.../core/uri/antlr/TestFullResourcePath.java | 56 +++-
samples/tutorials/p5_queryoptions-tis/pom.xml | 79 ++++++
.../myservice/mynamespace/data/Storage.java | 130 +++++++++
.../mynamespace/service/DemoEdmProvider.java | 154 +++++++++++
.../service/DemoEntityCollectionProcessor.java | 142 ++++++++++
.../service/DemoEntityProcessor.java | 118 ++++++++
.../service/DemoPrimitiveProcessor.java | 150 ++++++++++
.../java/myservice/mynamespace/util/Util.java | 105 +++++++
.../myservice/mynamespace/web/DemoServlet.java | 76 +++++
.../src/main/webapp/WEB-INF/web.xml | 40 +++
.../src/main/webapp/index.jsp | 26 ++
samples/tutorials/p6_queryoptions-es/pom.xml | 80 ++++++
.../myservice/mynamespace/data/Storage.java | 252 +++++++++++++++++
.../mynamespace/service/DemoEdmProvider.java | 211 ++++++++++++++
.../service/DemoEntityCollectionProcessor.java | 160 +++++++++++
.../service/DemoEntityProcessor.java | 235 ++++++++++++++++
.../service/DemoPrimitiveProcessor.java | 150 ++++++++++
.../java/myservice/mynamespace/util/Util.java | 149 ++++++++++
.../myservice/mynamespace/web/DemoServlet.java | 75 +++++
.../src/main/webapp/WEB-INF/web.xml | 34 +++
.../src/main/webapp/index.jsp | 43 +++
samples/tutorials/pom.xml | 2 +
80 files changed, 6057 insertions(+), 322 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/36659707/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/NavigationITCase.java
----------------------------------------------------------------------
diff --cc fit/src/test/java/org/apache/olingo/fit/tecsvc/client/NavigationITCase.java
index f129976,40c1de4..a153f06
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/NavigationITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/NavigationITCase.java
@@@ -20,7 -20,8 +20,10 @@@ package org.apache.olingo.fit.tecsvc.cl
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+ import static org.junit.Assert.assertTrue;
+
++import java.io.InputStream;
+
import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.api.domain.ClientEntity;
@@@ -31,23 -32,49 +34,57 @@@ import org.apache.olingo.commons.api.fo
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.fit.AbstractBaseTestITCase;
import org.apache.olingo.fit.tecsvc.TecSvcConst;
+ import org.apache.olingo.fit.util.StringHelper;
+import org.junit.Assert;
import org.junit.Test;
- public class NavigationITCase extends AbstractBaseTestITCase {
-import java.io.InputStream;
-
+ public final class NavigationITCase extends AbstractBaseTestITCase {
private final ODataClient client = getClient();
+
+ void assertShortOrInt(int value, Object n) {
+ if (n instanceof Number) {
+ assertEquals(value, ((Number)n).intValue());
+ } else {
+ Assert.fail();
+ }
+ }
+
@Test
+ public void navigationToEntityWithRelativeContextUrl() throws Exception {
+ // zero navigation
+ final InputStream zeroLevelResponse = client.getRetrieveRequestFactory().getEntityRequest(
+ client.newURIBuilder(TecSvcConst.BASE_URI)
+ .appendEntitySetSegment("ESAllPrim").
+ appendKeySegment(32767).build()).rawExecute();
+
+ String zeroLevelResponseBody = StringHelper.asString(zeroLevelResponse);
+ assertTrue(zeroLevelResponseBody.contains("\"@odata.context\":\"$metadata#ESAllPrim/$entity\""));
+
+ // one navigation
+ final InputStream oneLevelResponse = client.getRetrieveRequestFactory().getEntityRequest(
+ client.newURIBuilder(TecSvcConst.BASE_URI)
+ .appendEntitySetSegment("ESAllPrim").appendKeySegment(32767)
+ .appendNavigationSegment("NavPropertyETTwoPrimOne").build())
+ .rawExecute();
+
+ String oneLevelResponseBody = StringHelper.asString(oneLevelResponse);
+ assertTrue(oneLevelResponseBody.contains("\"@odata.context\":\"../$metadata#ESTwoPrim/$entity\""));
+
+ // two navigation
+ final InputStream twoLevelResponse = client.getRetrieveRequestFactory().getEntityRequest(
+ client.newURIBuilder(TecSvcConst.BASE_URI)
+ .appendEntitySetSegment("ESTwoPrim").appendKeySegment(32767)
+ .appendNavigationSegment("NavPropertyETAllPrimOne")
+ .appendNavigationSegment("NavPropertyETTwoPrimMany").appendKeySegment(-365).build())
+ .rawExecute();
+
+ String twoLevelResponseBody = StringHelper.asString(twoLevelResponse);
+ assertTrue(twoLevelResponseBody.contains("\"@odata.context\":\"../../$metadata#ESTwoPrim/$entity\""));
+ }
+
+ @Test
public void oneLevelToEntity() throws Exception {
final ODataRetrieveResponse<ClientEntity> response =
client.getRetrieveRequestFactory().getEntityRequest(
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/36659707/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/36659707/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/TechnicalServlet.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/36659707/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
----------------------------------------------------------------------
diff --cc lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
index 06f450d,a47f367..315623f
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
@@@ -147,7 -147,7 +147,7 @@@ public class TechnicalEntityProcessor e
checkRequestFormat(requestFormat);
//
-- if(odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).hasRespondAsync()) {
++ if (odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).hasRespondAsync()) {
TechnicalAsyncService asyncService = TechnicalAsyncService.getInstance();
TechnicalEntityProcessor processor = new TechnicalEntityProcessor(dataProvider, serviceMetadata);
processor.init(odata, serviceMetadata);
@@@ -161,7 -161,7 +161,6 @@@
}
//
--
final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) uriInfo.getUriResourceParts().get(0);
final EdmEntitySet edmEntitySet = resourceEntitySet.getEntitySet();
final EdmEntityType edmEntityType = edmEntitySet.getEntityType();
@@@ -173,7 -173,7 +172,7 @@@
dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()),
requestFormat.toContentTypeString());
} else {
-- final DeserializerResult deserializerResult =
++ final DeserializerResult deserializerResult =
odata.createDeserializer(requestFormat).entity(request.getBody(), edmEntityType);
new RequestValidator(dataProvider, request.getRawBaseUri())
.validate(edmEntitySet, deserializerResult.getEntity());
@@@ -187,8 -187,8 +186,8 @@@
+ odata.createUriHelper().buildCanonicalURL(edmEntitySet, entity);
final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
if (returnPreference == null || returnPreference == Return.REPRESENTATION) {
- response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, responseFormat, expand, null)
- .getContent());
+ response.setContent(serializeEntity(request, entity, edmEntitySet, edmEntityType, responseFormat, expand, null)
- .getContent());
++ .getContent());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
response.setStatusCode(HttpStatusCode.CREATED.getStatusCode());
} else {
@@@ -238,13 -238,13 +237,13 @@@
request.getRawBaseUri()).validate(edmEntitySet, changedEntity);
dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, changedEntity,
-- request.getMethod() == HttpMethod.PATCH, false);
++ request.getMethod() == HttpMethod.PATCH, false);
final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
if (returnPreference == null || returnPreference == Return.REPRESENTATION) {
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
- response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, responseFormat, null, null)
- .getContent());
+ response.setContent(serializeEntity(request, entity, edmEntitySet, edmEntityType, responseFormat)
- .getContent());
++ .getContent());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
} else {
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
@@@ -275,8 -275,8 +274,8 @@@
final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
if (returnPreference == null || returnPreference == Return.REPRESENTATION) {
- response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, responseFormat, null, null)
+ response.setContent(serializeEntity(request, entity, edmEntitySet, edmEntityType, responseFormat)
- .getContent());
+ .getContent());
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
} else {
@@@ -360,7 -360,7 +359,7 @@@
final UriResourceNavigation navigationProperty = getLastNavigation(uriInfo);
ensureNavigationPropertyNotNull(navigationProperty);
dataProvider.createReference(entity, navigationProperty.getProperty(), references.getEntityReferences().get(0),
-- request.getRawBaseUri());
++ request.getRawBaseUri());
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
}
@@@ -371,7 -371,7 +370,7 @@@
final UriResourceNavigation lastNavigation = getLastNavigation(uriInfo);
final IdOption idOption = uriInfo.getIdOption();
--
++
ensureNavigationPropertyNotNull(lastNavigation);
if (lastNavigation.isCollection() && idOption == null) {
throw new ODataApplicationException("Id system query option must be provided",
@@@ -393,8 -393,9 +392,9 @@@
}
@Override
- public void readReferenceCollection(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
- final ContentType requestedContentType) throws ODataApplicationException, ODataLibraryException {
+ public void readReferenceCollection(final ODataRequest request, final ODataResponse response,
- final UriInfo uriInfo, final ContentType requestedContentType)
- throws ODataApplicationException, ODataLibraryException {
++ final UriInfo uriInfo, final ContentType requestedContentType)
++ throws ODataApplicationException, ODataLibraryException {
readEntityCollection(request, response, uriInfo, requestedContentType, true);
}
@@@ -402,7 -403,7 +402,7 @@@
final ContentType requestedFormat, final boolean isReference)
throws ODataApplicationException, ODataLibraryException {
//
-- if(odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).hasRespondAsync()) {
++ if (odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).hasRespondAsync()) {
TechnicalAsyncService asyncService = TechnicalAsyncService.getInstance();
TechnicalEntityProcessor processor = new TechnicalEntityProcessor(dataProvider, serviceMetadata);
processor.init(odata, serviceMetadata);
@@@ -454,7 -455,7 +454,7 @@@
final UriInfo uriInfo, final ContentType requestedContentType, final boolean isReference)
throws ODataApplicationException, ODataLibraryException {
//
-- if(odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).hasRespondAsync()) {
++ if (odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).hasRespondAsync()) {
TechnicalAsyncService asyncService = TechnicalAsyncService.getInstance();
TechnicalEntityProcessor processor = new TechnicalEntityProcessor(dataProvider, serviceMetadata);
processor.init(odata, serviceMetadata);
@@@ -513,12 -514,12 +513,12 @@@
expandHandler.applyExpandQueryOptions(entitySetSerialization, edmEntitySet, expand);
final CountOption countOption = uriInfo.getCountOption();
- final String id = request.getRawBaseUri()+edmEntitySet.getName();
++ final String id = request.getRawBaseUri() + edmEntitySet.getName();
// Serialize
-- final SerializerResult serializerResult = (isReference) ?
++ final SerializerResult serializerResult = (isReference) ?
serializeReferenceCollection(entitySetSerialization, edmEntitySet, requestedContentType, countOption) :
- serializeEntityCollection(entitySetSerialization, edmEntitySet, edmEntityType, requestedContentType,
+ serializeEntityCollection(request, entitySetSerialization, edmEntitySet, edmEntityType, requestedContentType,
- expand, select, countOption);
-
+ expand, select, countOption, id);
response.setContent(serializerResult.getContent());
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
@@@ -528,59 -529,74 +528,73 @@@
}
}
- private SerializerResult serializeEntityCollection(final EntityCollection entityCollection,
- final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType, final ContentType requestedFormat,
- final ExpandOption expand, final SelectOption select, final CountOption countOption, String id)
- throws ODataLibraryException {
-
+ private SerializerResult serializeEntityCollection(final ODataRequest request, final EntityCollection
- entityCollection,
- final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType, final ContentType requestedFormat,
- final ExpandOption expand, final SelectOption select, final CountOption countOption)
- throws ODataLibraryException {
++ entityCollection, final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType,
++ final ContentType requestedFormat, final ExpandOption expand, final SelectOption select,
++ final CountOption countOption, String id) throws ODataLibraryException {
+
return odata.createSerializer(requestedFormat).entityCollection(
- serviceMetadata,
- edmEntityType,
- entityCollection,
- EntityCollectionSerializerOptions.with()
- .contextURL(isODataMetadataNone(requestedFormat) ? null :
- getContextUrl(request.getRawODataPath(), edmEntitySet, edmEntityType, false, expand,
- select))
- .count(countOption)
- .expand(expand).select(select)
- .build());
+ serviceMetadata,
+ edmEntityType,
+ entityCollection,
+ EntityCollectionSerializerOptions.with()
+ .contextURL(isODataMetadataNone(requestedFormat) ? null :
- getContextUrl(edmEntitySet, edmEntityType, false, expand, select))
++ getContextUrl(request.getRawODataPath(), edmEntitySet, edmEntityType, false, expand, select))
+ .count(countOption)
+ .expand(expand).select(select)
+ .setId(id)
+ .build());
}
-- private SerializerResult serializeReferenceCollection(final EntityCollection entityCollection,
-- final EdmEntitySet edmEntitySet, final ContentType requestedFormat, final CountOption countOption)
-- throws ODataLibraryException {
++ private SerializerResult serializeReferenceCollection(final EntityCollection entityCollection,
++ final EdmEntitySet edmEntitySet, final ContentType requestedFormat, final CountOption countOption)
++ throws ODataLibraryException {
return odata.createSerializer(requestedFormat)
- .referenceCollection(serviceMetadata, edmEntitySet, entityCollection,ReferenceCollectionSerializerOptions.with()
- .contextURL(ContextURL.with().asCollection().suffix(Suffix.REFERENCE).build())
- .count(countOption).build());
+ .referenceCollection(serviceMetadata, edmEntitySet, entityCollection,
- ReferenceCollectionSerializerOptions.with()
- .contextURL(ContextURL.with().asCollection().suffix(Suffix.REFERENCE).build())
- .count(countOption).build());
++ ReferenceCollectionSerializerOptions.with()
++ .contextURL(ContextURL.with().asCollection().suffix(Suffix.REFERENCE).build())
++ .count(countOption).build());
}
private SerializerResult serializeReference(final Entity entity, final EdmEntitySet edmEntitySet,
final ContentType requestedFormat) throws ODataLibraryException {
return odata.createSerializer(requestedFormat)
.reference(serviceMetadata, edmEntitySet, entity, ReferenceSerializerOptions.with()
- .contextURL(ContextURL.with().suffix(Suffix.REFERENCE).build()).build());
-
+ .contextURL(ContextURL.with().suffix(Suffix.REFERENCE).build()).build());
-
++
}
- private SerializerResult serializeEntity(final Entity entity,
- final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType, final ContentType requestedFormat,
- final ExpandOption expand, final SelectOption select) throws ODataLibraryException {
+ private SerializerResult serializeEntity(final ODataRequest request, final Entity entity,
- final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType,
- final ContentType requestedFormat) throws ODataLibraryException {
++ final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType,
++ final ContentType requestedFormat) throws ODataLibraryException {
+ return serializeEntity(request, entity, edmEntitySet, edmEntityType, requestedFormat, null, null);
+ }
+
+ private SerializerResult serializeEntity(final ODataRequest request, final Entity entity,
- final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType,
- final ContentType requestedFormat,
- final ExpandOption expand, final SelectOption select)
- throws ODataLibraryException {
++ final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType,
++ final ContentType requestedFormat,
++ final ExpandOption expand, final SelectOption select)
++ throws ODataLibraryException {
+
+ ContextURL contextUrl = isODataMetadataNone(requestedFormat) ? null :
- getContextUrl(request.getRawODataPath(), edmEntitySet, edmEntityType, true, expand, null);
++ getContextUrl(request.getRawODataPath(), edmEntitySet, edmEntityType, true, expand, null);
return odata.createSerializer(requestedFormat).entity(
- serviceMetadata,
- edmEntityType,
- entity,
- EntitySerializerOptions.with()
- .contextURL(contextUrl)
- .expand(expand).select(select)
- .build());
+ serviceMetadata,
+ edmEntityType,
+ entity,
+ EntitySerializerOptions.with()
- .contextURL(isODataMetadataNone(requestedFormat) ? null :
- getContextUrl(edmEntitySet, edmEntityType, true, expand, select))
++ .contextURL(contextUrl)
+ .expand(expand).select(select)
+ .build());
}
- private ContextURL getContextUrl(final EdmEntitySet entitySet, final EdmEntityType entityType,
- final boolean isSingleEntity, final ExpandOption expand, final SelectOption select) throws ODataLibraryException {
- Builder builder = ContextURL.with();
+ private ContextURL getContextUrl(String rawODataPath, final EdmEntitySet entitySet, final EdmEntityType entityType,
- final boolean isSingleEntity, final ExpandOption expand, final SelectOption select)
- throws ODataLibraryException {
++ final boolean isSingleEntity, final ExpandOption expand, final SelectOption select)
++ throws ODataLibraryException {
+ //
+ //
+ Builder builder = ContextURL.with().oDataPath(rawODataPath);
builder = entitySet == null ?
isSingleEntity ? builder.type(entityType) : builder.asCollection().type(entityType) :
builder.entitySet(entitySet);
@@@ -589,10 -605,10 +603,10 @@@
.suffix(isSingleEntity && entitySet != null ? Suffix.ENTITY : null);
return builder.build();
}
--
++
private void ensureNavigationPropertyNotNull(final UriResourceNavigation navigationProperty)
throws ODataApplicationException {
-- if(navigationProperty == null) {
++ if (navigationProperty == null) {
throw new ODataApplicationException("Missing navigation segment", HttpStatusCode.BAD_REQUEST.getStatusCode(),
Locale.ROOT);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/36659707/lib/server-test/pom.xml
----------------------------------------------------------------------
diff --cc lib/server-test/pom.xml
index 3173137,f698028..5edc346
--- a/lib/server-test/pom.xml
+++ b/lib/server-test/pom.xml
@@@ -66,13 -66,7 +66,12 @@@
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
- <scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>xmlunit</groupId>
+ <artifactId>xmlunit</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
[03/18] olingo-odata4 git commit: OLINGO-650: supporting the complex
properties in expand context url generation
Posted by ch...@apache.org.
OLINGO-650: supporting the complex properties in expand context url generation
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/8f763aad
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/8f763aad
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/8f763aad
Branch: refs/heads/OLINGO-640
Commit: 8f763aadea9730ddf518663a24da3d56aa2ae2e8
Parents: cb0f7f2
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Tue Jun 2 12:12:57 2015 -0500
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Thu Jul 23 18:48:34 2015 -0500
----------------------------------------------------------------------
.../core/serializer/utils/ContextURLHelper.java | 30 ++++++++++++++++++++
.../serializer/utils/ExpandSelectHelper.java | 11 ++-----
.../serializer/utils/ContextURLHelperTest.java | 16 +++++++++++
3 files changed, 49 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8f763aad/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java
index 421c6eb..f6c2ae3 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java
@@ -29,6 +29,8 @@ import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.commons.core.Encoder;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriParameter;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceProperty;
import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
import org.apache.olingo.server.api.uri.queryoption.SelectItem;
@@ -117,11 +119,39 @@ public final class ContextURLHelper {
}
result.append(Encoder.encode(propertyName)).append('(').append(innerSelectList).append(')');
}
+ } else {
+ final List<UriResource> resourceParts = expandItem.getResourcePath().getUriResourceParts();
+ if(resourceParts.size() > 1) {
+ if (result.length() > 0) {
+ result.append(',');
+ }
+ final List<String> path = getPropertyPath(resourceParts);
+ String propertyPath = buildPropertyPath(path);
+ result.append(Encoder.encode(propertyName));
+ result.append("/").append(propertyPath);
+ }
}
}
}
}
+ private static List<String> getPropertyPath(final List<UriResource> path) {
+ List<String> result = new LinkedList<String>();
+ int index = 1;
+ while (index < path.size() && path.get(index) instanceof UriResourceProperty) {
+ result.add(((UriResourceProperty) path.get(index)).getProperty().getName());
+ index++;
+ }
+ return result;
+ }
+
+ private static String buildPropertyPath(final List<String> path) {
+ StringBuilder result = new StringBuilder();
+ for (final String segment : path) {
+ result.append(result.length() == 0 ? "" : '/').append(Encoder.encode(segment)); //$NON-NLS-1$
+ }
+ return result.length() == 0?null:result.toString();
+ }
private static List<List<String>> getComplexSelectedPaths(final EdmProperty edmProperty,
final Set<List<String>> selectedPaths) {
List<List<String>> result = new ArrayList<List<String>>();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8f763aad/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ExpandSelectHelper.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ExpandSelectHelper.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ExpandSelectHelper.java
index 3acdbd3..30810f0 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ExpandSelectHelper.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ExpandSelectHelper.java
@@ -127,14 +127,9 @@ public abstract class ExpandSelectHelper {
Set<String> expanded = new HashSet<String>();
for (final ExpandItem item : expandItems) {
final List<UriResource> resourceParts = item.getResourcePath().getUriResourceParts();
- if (resourceParts.size() == 1) {
- final UriResource resource = resourceParts.get(0);
- if (resource instanceof UriResourceNavigation) {
- expanded.add(((UriResourceNavigation) resource).getProperty().getName());
- }
- } else {
- throw new SerializerException("Expand is not supported within complex properties.",
- SerializerException.MessageKeys.NOT_IMPLEMENTED);
+ final UriResource resource = resourceParts.get(0);
+ if (resource instanceof UriResourceNavigation) {
+ expanded.add(((UriResourceNavigation) resource).getProperty().getName());
}
}
return expanded;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8f763aad/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java
index 2416fbe..b94f97e 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java
@@ -117,6 +117,22 @@ public class ContextURLHelperTest {
}
@Test
+ public void buildExpandWithNavigationProperty() throws Exception {
+ final EdmEntitySet entitySet = entityContainer.getEntitySet("ESTwoPrim");
+ final ExpandOption expand = ExpandSelectMock.mockExpandOption(Arrays.asList(
+ ExpandSelectMock.mockExpandItem(entitySet, "NavPropertyETAllPrimOne", "PropertyString")));
+ final SelectItem selectItem1 = ExpandSelectMock.mockSelectItem(entitySet, "PropertyInt16");
+ final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(
+ selectItem1));
+
+ final ContextURL contextURL = ContextURL.with().entitySet(entitySet)
+ .selectList(ContextURLHelper.buildSelectList(entitySet.getEntityType(), expand, select)).build();
+ assertEquals("$metadata#ESTwoPrim(PropertyInt16,NavPropertyETAllPrimOne/PropertyString)",
+ ContextURLBuilder.create(contextURL).toASCIIString());
+ }
+
+
+ @Test
public void buildExpandSelect() throws Exception {
final EdmEntitySet entitySet = entityContainer.getEntitySet("ESTwoPrim");
final ExpandItem expandItem1 = ExpandSelectMock.mockExpandItem(entitySet, "NavPropertyETAllPrimOne");
[17/18] olingo-odata4 git commit: [OLINGO-640] Minor adjustments to
tests and deleted logger
Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/db0b9d39/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java
index abce52d..50d432c 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java
@@ -18,8 +18,10 @@
*/
package org.apache.olingo.server.core.serializer.xml;
+import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
+import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
@@ -63,6 +65,9 @@ import org.apache.olingo.server.core.uri.UriHelperImpl;
import org.apache.olingo.server.tecsvc.MetadataETagSupport;
import org.apache.olingo.server.tecsvc.data.DataProvider;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
+import org.custommonkey.xmlunit.Diff;
+import org.custommonkey.xmlunit.Difference;
+import org.custommonkey.xmlunit.DifferenceListener;
import org.custommonkey.xmlunit.XMLAssert;
import org.custommonkey.xmlunit.XMLUnit;
import org.hamcrest.CoreMatchers;
@@ -70,11 +75,17 @@ import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
-public class ODataXmlSerializerTest {
+public class ODataXmlSerializerTest {
private static final ServiceMetadata metadata = new ServiceMetadataImpl(
new EdmTechProvider(), Collections.<EdmxReference> emptyList(), new MetadataETagSupport("WmetadataETag"));
private static final EdmEntityContainer entityContainer = metadata.getEdm().getEntityContainer();
+ private static final DifferenceListener DIFFERENCE_LISTENER = new CustomDifferenceListener();
+ private static final int MAX_ALLOWED_UPDATED_DIFFERENCE = 2000;
+ private static final String UPDATED_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
+
private final DataProvider data = new DataProvider(metadata.getEdm());
private final ODataSerializer serializer = new ODataXmlSerializer();
private final UriHelper helper = new UriHelperImpl();
@@ -87,69 +98,70 @@ public class ODataXmlSerializerTest {
XMLUnit.setNormalizeWhitespace(true);
XMLUnit.setCompareUnmatched(false);
}
-
+
@Test
public void entitySimple() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
+ long currentTimeMillis = System.currentTimeMillis();
InputStream result = serializer.entity(metadata, edmEntitySet.getEntityType(), entity,
EntitySerializerOptions.with()
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
.build()).getContent();
final String resultString = IOUtils.toString(result);
- String expected = "<?xml version='1.0' encoding='UTF-8'?>\n" +
+ String expected = "<?xml version='1.0' encoding='UTF-8'?>\n" +
"<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\" "
- + "xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
+ + "xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" "
- + "m:context=\"$metadata#ESAllPrim/$entity\"\n" +
- " m:metadata-etag=\"WmetadataETag\">\n" +
- " <a:id>ESAllPrim(32767)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- " <a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESAllPrim(32767)\" />\n" +
- " <a:link\n" +
- " rel=\"http://docs.oasis-open.org/odata/ns/related/NavPropertyETTwoPrimOne\"\n" +
- " type=\"application/atom+xml;type=entry\" title=\"NavPropertyETTwoPrimOne\"\n" +
- " href=\"ESTwoPrim(32767)\" />\n" +
- " <a:link\n" +
- " rel=\"http://docs.oasis-open.org/odata/ns/related/NavPropertyETTwoPrimMany\"\n" +
- " type=\"application/atom+xml;type=feed\" title=\"NavPropertyETTwoPrimMany\"\n" +
- " href=\"ESAllPrim(32767)/NavPropertyETTwoPrimMany\" />\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETAllPrim\" />\n" +
- " <a:content type=\"application/xml\">\n" +
- " <m:properties>\n" +
- " <d:PropertyInt16 m:type=\"Int16\">32767</d:PropertyInt16>\n" +
- " <d:PropertyString>First Resource - positive values</d:PropertyString>\n" +
- " <d:PropertyBoolean m:type=\"Boolean\">true</d:PropertyBoolean>\n" +
- " <d:PropertyByte m:type=\"Byte\">255</d:PropertyByte>\n" +
- " <d:PropertySByte m:type=\"SByte\">127</d:PropertySByte>\n" +
- " <d:PropertyInt32 m:type=\"Int32\">2147483647</d:PropertyInt32>\n" +
- " <d:PropertyInt64 m:type=\"Int64\">9223372036854775807\n" +
- " </d:PropertyInt64>\n" +
- " <d:PropertySingle m:type=\"Single\">1.79E20</d:PropertySingle>\n" +
- " <d:PropertyDouble m:type=\"Double\">-1.79E19</d:PropertyDouble>\n" +
- " <d:PropertyDecimal m:type=\"Decimal\">34</d:PropertyDecimal>\n" +
- " <d:PropertyBinary m:type=\"Binary\">ASNFZ4mrze8=\n" +
- " </d:PropertyBinary>\n" +
- " <d:PropertyDate m:type=\"Date\">2012-12-03</d:PropertyDate>\n" +
- " <d:PropertyDateTimeOffset m:type=\"DateTimeOffset\">2012-12-03T07:16:23Z\n" +
- " </d:PropertyDateTimeOffset>\n" +
- " <d:PropertyDuration m:type=\"Duration\">PT6S\n" +
- " </d:PropertyDuration>\n" +
- " <d:PropertyGuid m:type=\"Guid\">01234567-89ab-cdef-0123-456789abcdef\n" +
- " </d:PropertyGuid>\n" +
- " <d:PropertyTimeOfDay m:type=\"TimeOfDay\">03:26:05\n" +
- " </d:PropertyTimeOfDay>\n" +
- " </m:properties>\n" +
- " </a:content>\n" +
+ + "m:context=\"$metadata#ESAllPrim/$entity\"\n" +
+ " m:metadata-etag=\"WmetadataETag\">\n" +
+ " <a:id>ESAllPrim(32767)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ " <a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESAllPrim(32767)\" />\n" +
+ " <a:link\n" +
+ " rel=\"http://docs.oasis-open.org/odata/ns/related/NavPropertyETTwoPrimOne\"\n" +
+ " type=\"application/atom+xml;type=entry\" title=\"NavPropertyETTwoPrimOne\"\n" +
+ " href=\"ESTwoPrim(32767)\" />\n" +
+ " <a:link\n" +
+ " rel=\"http://docs.oasis-open.org/odata/ns/related/NavPropertyETTwoPrimMany\"\n" +
+ " type=\"application/atom+xml;type=feed\" title=\"NavPropertyETTwoPrimMany\"\n" +
+ " href=\"ESAllPrim(32767)/NavPropertyETTwoPrimMany\" />\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETAllPrim\" />\n" +
+ " <a:content type=\"application/xml\">\n" +
+ " <m:properties>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">32767</d:PropertyInt16>\n" +
+ " <d:PropertyString>First Resource - positive values</d:PropertyString>\n" +
+ " <d:PropertyBoolean m:type=\"Boolean\">true</d:PropertyBoolean>\n" +
+ " <d:PropertyByte m:type=\"Byte\">255</d:PropertyByte>\n" +
+ " <d:PropertySByte m:type=\"SByte\">127</d:PropertySByte>\n" +
+ " <d:PropertyInt32 m:type=\"Int32\">2147483647</d:PropertyInt32>\n" +
+ " <d:PropertyInt64 m:type=\"Int64\">9223372036854775807\n" +
+ " </d:PropertyInt64>\n" +
+ " <d:PropertySingle m:type=\"Single\">1.79E20</d:PropertySingle>\n" +
+ " <d:PropertyDouble m:type=\"Double\">-1.79E19</d:PropertyDouble>\n" +
+ " <d:PropertyDecimal m:type=\"Decimal\">34</d:PropertyDecimal>\n" +
+ " <d:PropertyBinary m:type=\"Binary\">ASNFZ4mrze8=\n" +
+ " </d:PropertyBinary>\n" +
+ " <d:PropertyDate m:type=\"Date\">2012-12-03</d:PropertyDate>\n" +
+ " <d:PropertyDateTimeOffset m:type=\"DateTimeOffset\">2012-12-03T07:16:23Z\n" +
+ " </d:PropertyDateTimeOffset>\n" +
+ " <d:PropertyDuration m:type=\"Duration\">PT6S\n" +
+ " </d:PropertyDuration>\n" +
+ " <d:PropertyGuid m:type=\"Guid\">01234567-89ab-cdef-0123-456789abcdef\n" +
+ " </d:PropertyGuid>\n" +
+ " <d:PropertyTimeOfDay m:type=\"TimeOfDay\">03:26:05\n" +
+ " </d:PropertyTimeOfDay>\n" +
+ " </m:properties>\n" +
+ " </a:content>\n" +
"</a:entry>";
- XMLAssert.assertXMLEqual(expected, resultString);
+ checkXMLEqual(expected, resultString);
}
@Test
@@ -157,60 +169,62 @@ public class ODataXmlSerializerTest {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
entity.getProperties().retainAll(Arrays.asList(entity.getProperties().get(0)));
- final String resultString = IOUtils.toString(serializer.entity(metadata, edmEntitySet.getEntityType(),
+ long currentTimeMillis = System.currentTimeMillis();
+ InputStream content = serializer.entity(metadata, edmEntitySet.getEntityType(),
entity,
EntitySerializerOptions.with()
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
- .build()).getContent());
- String expected = "<?xml version='1.0' encoding='UTF-8'?>\n" +
- "<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\"\n" +
- " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
- " xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" "+
- "m:context=\"$metadata#ESAllPrim/$entity\"\n" +
- " m:metadata-etag=\"WmetadataETag\">\n" +
- " <a:id>ESAllPrim(32767)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- " <a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESAllPrim(32767)\"/>\n" +
- " <a:link\n" +
- " rel=\"http://docs.oasis-open.org/odata/ns/related/NavPropertyETTwoPrimOne\"\n" +
- " type=\"application/atom+xml;type=entry\" title=\"NavPropertyETTwoPrimOne\"\n" +
+ .build()).getContent();
+ final String resultString = IOUtils.toString(content);
+ String expected = "<?xml version='1.0' encoding='UTF-8'?>\n" +
+ "<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\"\n" +
+ " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
+ " xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" " +
+ "m:context=\"$metadata#ESAllPrim/$entity\"\n" +
+ " m:metadata-etag=\"WmetadataETag\">\n" +
+ " <a:id>ESAllPrim(32767)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ " <a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESAllPrim(32767)\"/>\n" +
+ " <a:link\n" +
+ " rel=\"http://docs.oasis-open.org/odata/ns/related/NavPropertyETTwoPrimOne\"\n" +
+ " type=\"application/atom+xml;type=entry\" title=\"NavPropertyETTwoPrimOne\"\n" +
" href=\"ESTwoPrim(32767)\" />\n" +
- " <a:link\n" +
- " rel=\"http://docs.oasis-open.org/odata/ns/related/NavPropertyETTwoPrimMany\"\n" +
- " type=\"application/atom+xml;type=feed\" title=\"NavPropertyETTwoPrimMany\"\n" +
- " href=\"ESAllPrim(32767)/NavPropertyETTwoPrimMany\" />\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETAllPrim\" />\n" +
- " <a:content type=\"application/xml\">\n" +
- " <m:properties>\n" +
- " <d:PropertyInt16 m:type=\"Int16\">32767</d:PropertyInt16>\n" +
- " <d:PropertyString m:null=\"true\" />\n" +
- " <d:PropertyBoolean m:null=\"true\" />\n" +
- " <d:PropertyByte m:null=\"true\" />\n" +
- " <d:PropertySByte m:null=\"true\" />\n" +
- " <d:PropertyInt32 m:null=\"true\" />\n" +
- " <d:PropertyInt64 m:null=\"true\" />\n" +
- " <d:PropertySingle m:null=\"true\" />\n" +
- " <d:PropertyDouble m:null=\"true\" />\n" +
- " <d:PropertyDecimal m:null=\"true\" />\n" +
- " <d:PropertyBinary m:null=\"true\" />\n" +
- " <d:PropertyDate m:null=\"true\" />\n" +
- " <d:PropertyDateTimeOffset\n" +
- " m:null=\"true\" />\n" +
- " <d:PropertyDuration m:null=\"true\" />\n" +
- " <d:PropertyGuid m:null=\"true\" />\n" +
- " <d:PropertyTimeOfDay m:null=\"true\" />\n" +
- " </m:properties>\n" +
- " </a:content>\n" +
- "</a:entry>\n" +
- "";
- XMLAssert.assertXMLEqual(expected, resultString);
+ " <a:link\n" +
+ " rel=\"http://docs.oasis-open.org/odata/ns/related/NavPropertyETTwoPrimMany\"\n" +
+ " type=\"application/atom+xml;type=feed\" title=\"NavPropertyETTwoPrimMany\"\n" +
+ " href=\"ESAllPrim(32767)/NavPropertyETTwoPrimMany\" />\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETAllPrim\" />\n" +
+ " <a:content type=\"application/xml\">\n" +
+ " <m:properties>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">32767</d:PropertyInt16>\n" +
+ " <d:PropertyString m:null=\"true\" />\n" +
+ " <d:PropertyBoolean m:null=\"true\" />\n" +
+ " <d:PropertyByte m:null=\"true\" />\n" +
+ " <d:PropertySByte m:null=\"true\" />\n" +
+ " <d:PropertyInt32 m:null=\"true\" />\n" +
+ " <d:PropertyInt64 m:null=\"true\" />\n" +
+ " <d:PropertySingle m:null=\"true\" />\n" +
+ " <d:PropertyDouble m:null=\"true\" />\n" +
+ " <d:PropertyDecimal m:null=\"true\" />\n" +
+ " <d:PropertyBinary m:null=\"true\" />\n" +
+ " <d:PropertyDate m:null=\"true\" />\n" +
+ " <d:PropertyDateTimeOffset\n" +
+ " m:null=\"true\" />\n" +
+ " <d:PropertyDuration m:null=\"true\" />\n" +
+ " <d:PropertyGuid m:null=\"true\" />\n" +
+ " <d:PropertyTimeOfDay m:null=\"true\" />\n" +
+ " </m:properties>\n" +
+ " </a:content>\n" +
+ "</a:entry>\n" +
+ "";
+ checkXMLEqual(expected, resultString);
}
@Test(expected = SerializerException.class)
@@ -254,7 +268,7 @@ public class ODataXmlSerializerTest {
InputStream result = serializer.entityCollection(metadata, edmEntitySet.getEntityType(), entitySet,
EntityCollectionSerializerOptions.with()
.contextURL(ContextURL.with().serviceRoot(new URI("http://host:port"))
- .entitySet(edmEntitySet).build())
+ .entitySet(edmEntitySet).build())
.setId("http://host/svc/ESCompAllPrim")
.count(countOption)
.build()).getContent();
@@ -277,228 +291,231 @@ public class ODataXmlSerializerTest {
public void entityCollAllPrim() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCollAllPrim");
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
+ long currentTimeMillis = System.currentTimeMillis();
InputStream result = serializer.entity(metadata, edmEntitySet.getEntityType(), entity,
EntitySerializerOptions.with()
.contextURL(ContextURL.with().serviceRoot(URI.create("http://host/service/"))
.entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
.build()).getContent();
final String resultString = IOUtils.toString(result);
- String expected = "<?xml version='1.0' encoding='UTF-8'?>\n" +
+ String expected = "<?xml version='1.0' encoding='UTF-8'?>\n" +
"<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\" "
- + "xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
+ + "xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" "
- + "m:context=\"http://host/service/$metadata#ESCollAllPrim/$entity\"\n" +
- " m:metadata-etag=\"WmetadataETag\">\n" +
- " <a:id>ESCollAllPrim(1)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- "<a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESCollAllPrim(1)\" />\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETCollAllPrim\" />\n" +
- " <a:content type=\"application/xml\">\n" +
- " <m:properties>\n" +
- " <d:PropertyInt16 m:type=\"Int16\">1</d:PropertyInt16>\n" +
- " <d:CollPropertyString m:type=\"#Collection(String)\">\n" +
- " <m:element>Employee1@company.example</m:element>\n" +
- " <m:element>Employee2@company.example</m:element>\n" +
- " <m:element>Employee3@company.example</m:element>\n" +
- " </d:CollPropertyString>\n" +
- " <d:CollPropertyBoolean m:type=\"#Collection(Boolean)\">\n" +
- " <m:element>true</m:element>\n" +
- " <m:element>false</m:element>\n" +
- " <m:element>true</m:element>\n" +
- " </d:CollPropertyBoolean>\n" +
- " <d:CollPropertyByte m:type=\"#Collection(Byte)\">\n" +
- " <m:element>50</m:element>\n" +
- " <m:element>200</m:element>\n" +
- " <m:element>249</m:element>\n" +
- " </d:CollPropertyByte>\n" +
- " <d:CollPropertySByte m:type=\"#Collection(SByte)\">\n" +
- " <m:element>-120</m:element>\n" +
- " <m:element>120</m:element>\n" +
- " <m:element>126</m:element>\n" +
- " </d:CollPropertySByte>\n" +
- " <d:CollPropertyInt16 m:type=\"#Collection(Int16)\">\n" +
- " <m:element>1000</m:element>\n" +
- " <m:element>2000</m:element>\n" +
- " <m:element>30112</m:element>\n" +
- " </d:CollPropertyInt16>\n" +
- " <d:CollPropertyInt32 m:type=\"#Collection(Int32)\">\n" +
- " <m:element>23232323</m:element>\n" +
- " <m:element>11223355</m:element>\n" +
- " <m:element>10000001</m:element>\n" +
- " </d:CollPropertyInt32>\n" +
- " <d:CollPropertyInt64 m:type=\"#Collection(Int64)\">\n" +
- " <m:element>929292929292</m:element>\n" +
- " <m:element>333333333333</m:element>\n" +
- " <m:element>444444444444</m:element>\n" +
- " </d:CollPropertyInt64>\n" +
- " <d:CollPropertySingle m:type=\"#Collection(Single)\">\n" +
- " <m:element>1790.0</m:element>\n" +
- " <m:element>26600.0</m:element>\n" +
- " <m:element>3210.0</m:element>\n" +
- " </d:CollPropertySingle>\n" +
- " <d:CollPropertyDouble m:type=\"#Collection(Double)\">\n" +
- " <m:element>-17900.0</m:element>\n" +
- " <m:element>-2.78E7</m:element>\n" +
- " <m:element>3210.0</m:element>\n" +
- " </d:CollPropertyDouble>\n" +
- " <d:CollPropertyDecimal m:type=\"#Collection(Decimal)\">\n" +
- " <m:element>12</m:element>\n" +
- " <m:element>-2</m:element>\n" +
- " <m:element>1234</m:element>\n" +
- " </d:CollPropertyDecimal>\n" +
- " <d:CollPropertyBinary m:type=\"#Collection(Binary)\">\n" +
- " <m:element>q83v</m:element>\n" +
- " <m:element>ASNF</m:element>\n" +
- " <m:element>VGeJ</m:element>\n" +
- " </d:CollPropertyBinary>\n" +
- " <d:CollPropertyDate m:type=\"#Collection(Date)\">\n" +
- " <m:element>1958-12-03</m:element>\n" +
- " <m:element>1999-08-05</m:element>\n" +
- " <m:element>2013-06-25</m:element>\n" +
- " </d:CollPropertyDate>\n" +
- " <d:CollPropertyDateTimeOffset m:type=\"#Collection(DateTimeOffset)\">\n" +
- " <m:element>2015-08-12T03:08:34Z</m:element>\n" +
- " <m:element>1970-03-28T12:11:10Z</m:element>\n" +
- " <m:element>1948-02-17T09:09:09Z</m:element>\n" +
- " </d:CollPropertyDateTimeOffset>\n" +
- " <d:CollPropertyDuration m:type=\"#Collection(Duration)\">\n" +
- " <m:element>PT13S</m:element>\n" +
- " <m:element>PT5H28M0S</m:element>\n" +
- " <m:element>PT1H0S</m:element>\n" +
- " </d:CollPropertyDuration>\n" +
- " <d:CollPropertyGuid m:type=\"#Collection(Guid)\">\n" +
- " <m:element>ffffff67-89ab-cdef-0123-456789aaaaaa</m:element>\n" +
- " <m:element>eeeeee67-89ab-cdef-0123-456789bbbbbb</m:element>\n" +
- " <m:element>cccccc67-89ab-cdef-0123-456789cccccc</m:element>\n" +
- " </d:CollPropertyGuid>\n" +
- " <d:CollPropertyTimeOfDay m:type=\"#Collection(TimeOfDay)\">\n" +
- " <m:element>04:14:13</m:element>\n" +
- " <m:element>23:59:59</m:element>\n" +
- " <m:element>01:12:33</m:element>\n" +
- " </d:CollPropertyTimeOfDay>\n" +
- " </m:properties>\n" +
- " </a:content>\n" +
+ + "m:context=\"http://host/service/$metadata#ESCollAllPrim/$entity\"\n" +
+ " m:metadata-etag=\"WmetadataETag\">\n" +
+ " <a:id>ESCollAllPrim(1)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ "<a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESCollAllPrim(1)\" />\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETCollAllPrim\" />\n" +
+ " <a:content type=\"application/xml\">\n" +
+ " <m:properties>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">1</d:PropertyInt16>\n" +
+ " <d:CollPropertyString m:type=\"#Collection(String)\">\n" +
+ " <m:element>Employee1@company.example</m:element>\n" +
+ " <m:element>Employee2@company.example</m:element>\n" +
+ " <m:element>Employee3@company.example</m:element>\n" +
+ " </d:CollPropertyString>\n" +
+ " <d:CollPropertyBoolean m:type=\"#Collection(Boolean)\">\n" +
+ " <m:element>true</m:element>\n" +
+ " <m:element>false</m:element>\n" +
+ " <m:element>true</m:element>\n" +
+ " </d:CollPropertyBoolean>\n" +
+ " <d:CollPropertyByte m:type=\"#Collection(Byte)\">\n" +
+ " <m:element>50</m:element>\n" +
+ " <m:element>200</m:element>\n" +
+ " <m:element>249</m:element>\n" +
+ " </d:CollPropertyByte>\n" +
+ " <d:CollPropertySByte m:type=\"#Collection(SByte)\">\n" +
+ " <m:element>-120</m:element>\n" +
+ " <m:element>120</m:element>\n" +
+ " <m:element>126</m:element>\n" +
+ " </d:CollPropertySByte>\n" +
+ " <d:CollPropertyInt16 m:type=\"#Collection(Int16)\">\n" +
+ " <m:element>1000</m:element>\n" +
+ " <m:element>2000</m:element>\n" +
+ " <m:element>30112</m:element>\n" +
+ " </d:CollPropertyInt16>\n" +
+ " <d:CollPropertyInt32 m:type=\"#Collection(Int32)\">\n" +
+ " <m:element>23232323</m:element>\n" +
+ " <m:element>11223355</m:element>\n" +
+ " <m:element>10000001</m:element>\n" +
+ " </d:CollPropertyInt32>\n" +
+ " <d:CollPropertyInt64 m:type=\"#Collection(Int64)\">\n" +
+ " <m:element>929292929292</m:element>\n" +
+ " <m:element>333333333333</m:element>\n" +
+ " <m:element>444444444444</m:element>\n" +
+ " </d:CollPropertyInt64>\n" +
+ " <d:CollPropertySingle m:type=\"#Collection(Single)\">\n" +
+ " <m:element>1790.0</m:element>\n" +
+ " <m:element>26600.0</m:element>\n" +
+ " <m:element>3210.0</m:element>\n" +
+ " </d:CollPropertySingle>\n" +
+ " <d:CollPropertyDouble m:type=\"#Collection(Double)\">\n" +
+ " <m:element>-17900.0</m:element>\n" +
+ " <m:element>-2.78E7</m:element>\n" +
+ " <m:element>3210.0</m:element>\n" +
+ " </d:CollPropertyDouble>\n" +
+ " <d:CollPropertyDecimal m:type=\"#Collection(Decimal)\">\n" +
+ " <m:element>12</m:element>\n" +
+ " <m:element>-2</m:element>\n" +
+ " <m:element>1234</m:element>\n" +
+ " </d:CollPropertyDecimal>\n" +
+ " <d:CollPropertyBinary m:type=\"#Collection(Binary)\">\n" +
+ " <m:element>q83v</m:element>\n" +
+ " <m:element>ASNF</m:element>\n" +
+ " <m:element>VGeJ</m:element>\n" +
+ " </d:CollPropertyBinary>\n" +
+ " <d:CollPropertyDate m:type=\"#Collection(Date)\">\n" +
+ " <m:element>1958-12-03</m:element>\n" +
+ " <m:element>1999-08-05</m:element>\n" +
+ " <m:element>2013-06-25</m:element>\n" +
+ " </d:CollPropertyDate>\n" +
+ " <d:CollPropertyDateTimeOffset m:type=\"#Collection(DateTimeOffset)\">\n" +
+ " <m:element>2015-08-12T03:08:34Z</m:element>\n" +
+ " <m:element>1970-03-28T12:11:10Z</m:element>\n" +
+ " <m:element>1948-02-17T09:09:09Z</m:element>\n" +
+ " </d:CollPropertyDateTimeOffset>\n" +
+ " <d:CollPropertyDuration m:type=\"#Collection(Duration)\">\n" +
+ " <m:element>PT13S</m:element>\n" +
+ " <m:element>PT5H28M0S</m:element>\n" +
+ " <m:element>PT1H0S</m:element>\n" +
+ " </d:CollPropertyDuration>\n" +
+ " <d:CollPropertyGuid m:type=\"#Collection(Guid)\">\n" +
+ " <m:element>ffffff67-89ab-cdef-0123-456789aaaaaa</m:element>\n" +
+ " <m:element>eeeeee67-89ab-cdef-0123-456789bbbbbb</m:element>\n" +
+ " <m:element>cccccc67-89ab-cdef-0123-456789cccccc</m:element>\n" +
+ " </d:CollPropertyGuid>\n" +
+ " <d:CollPropertyTimeOfDay m:type=\"#Collection(TimeOfDay)\">\n" +
+ " <m:element>04:14:13</m:element>\n" +
+ " <m:element>23:59:59</m:element>\n" +
+ " <m:element>01:12:33</m:element>\n" +
+ " </d:CollPropertyTimeOfDay>\n" +
+ " </m:properties>\n" +
+ " </a:content>\n" +
"</a:entry>";
- XMLAssert.assertXMLEqual(expected, resultString);
+ checkXMLEqual(expected, resultString);
}
@Test
public void entityCompAllPrim() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompAllPrim");
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
+ long currentTimeMillis = System.currentTimeMillis();
InputStream result = serializer.entity(metadata, edmEntitySet.getEntityType(), entity,
EntitySerializerOptions.with()
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
.build()).getContent();
-
+
final String resultString = IOUtils.toString(result);
- String expected = "<?xml version='1.0' encoding='UTF-8'?>\n" +
+ String expected = "<?xml version='1.0' encoding='UTF-8'?>\n" +
"<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\" "
- + "xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
+ + "xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" "
- + "m:context=\"$metadata#ESCompAllPrim/$entity\"\n" +
- " m:metadata-etag=\"WmetadataETag\" m:etag=\"W/"32767"\">\n" +
- " <a:id>ESCompAllPrim(32767)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- "<a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESCompAllPrim(32767)\" />\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETCompAllPrim\" />\n" +
- " <a:content type=\"application/xml\">\n" +
- " <m:properties>\n" +
- " <d:PropertyInt16 m:type=\"Int16\">32767</d:PropertyInt16>\n" +
- " <d:PropertyComp m:type=\"#olingo.odata.test1.CTAllPrim\">\n" +
- " <d:PropertyString>First Resource - first</d:PropertyString>\n" +
- " <d:PropertyBinary m:type=\"Binary\">ASNFZ4mrze8=</d:PropertyBinary>\n" +
- " <d:PropertyBoolean m:type=\"Boolean\">true</d:PropertyBoolean>\n" +
- " <d:PropertyByte m:type=\"Byte\">255</d:PropertyByte>\n" +
- " <d:PropertyDate m:type=\"Date\">2012-10-03</d:PropertyDate>\n" +
+ + "m:context=\"$metadata#ESCompAllPrim/$entity\"\n" +
+ " m:metadata-etag=\"WmetadataETag\" m:etag=\"W/"32767"\">\n" +
+ " <a:id>ESCompAllPrim(32767)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ "<a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESCompAllPrim(32767)\" />\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETCompAllPrim\" />\n" +
+ " <a:content type=\"application/xml\">\n" +
+ " <m:properties>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">32767</d:PropertyInt16>\n" +
+ " <d:PropertyComp m:type=\"#olingo.odata.test1.CTAllPrim\">\n" +
+ " <d:PropertyString>First Resource - first</d:PropertyString>\n" +
+ " <d:PropertyBinary m:type=\"Binary\">ASNFZ4mrze8=</d:PropertyBinary>\n" +
+ " <d:PropertyBoolean m:type=\"Boolean\">true</d:PropertyBoolean>\n" +
+ " <d:PropertyByte m:type=\"Byte\">255</d:PropertyByte>\n" +
+ " <d:PropertyDate m:type=\"Date\">2012-10-03</d:PropertyDate>\n" +
" <d:PropertyDateTimeOffset m:type=\"DateTimeOffset\">2012-10-03T07:16:23.1234567Z"
- + "</d:PropertyDateTimeOffset>\n" +
- " <d:PropertyDecimal m:type=\"Decimal\">34.27</d:PropertyDecimal>\n" +
- " <d:PropertySingle m:type=\"Single\">1.79E20</d:PropertySingle>\n" +
- " <d:PropertyDouble m:type=\"Double\">-1.79E19</d:PropertyDouble>\n" +
- " <d:PropertyDuration m:type=\"Duration\">PT6S</d:PropertyDuration>\n" +
- " <d:PropertyGuid m:type=\"Guid\">01234567-89ab-cdef-0123-456789abcdef</d:PropertyGuid>\n" +
- " <d:PropertyInt16 m:type=\"Int16\">32767</d:PropertyInt16>\n" +
- " <d:PropertyInt32 m:type=\"Int32\">2147483647</d:PropertyInt32>\n" +
- " <d:PropertyInt64 m:type=\"Int64\">9223372036854775807</d:PropertyInt64>\n" +
- " <d:PropertySByte m:type=\"SByte\">127</d:PropertySByte>\n" +
- " <d:PropertyTimeOfDay m:type=\"TimeOfDay\">01:00:01</d:PropertyTimeOfDay>\n" +
- " </d:PropertyComp>\n" +
- " </m:properties>\n" +
- " </a:content>\n" +
+ + "</d:PropertyDateTimeOffset>\n" +
+ " <d:PropertyDecimal m:type=\"Decimal\">34.27</d:PropertyDecimal>\n" +
+ " <d:PropertySingle m:type=\"Single\">1.79E20</d:PropertySingle>\n" +
+ " <d:PropertyDouble m:type=\"Double\">-1.79E19</d:PropertyDouble>\n" +
+ " <d:PropertyDuration m:type=\"Duration\">PT6S</d:PropertyDuration>\n" +
+ " <d:PropertyGuid m:type=\"Guid\">01234567-89ab-cdef-0123-456789abcdef</d:PropertyGuid>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">32767</d:PropertyInt16>\n" +
+ " <d:PropertyInt32 m:type=\"Int32\">2147483647</d:PropertyInt32>\n" +
+ " <d:PropertyInt64 m:type=\"Int64\">9223372036854775807</d:PropertyInt64>\n" +
+ " <d:PropertySByte m:type=\"SByte\">127</d:PropertySByte>\n" +
+ " <d:PropertyTimeOfDay m:type=\"TimeOfDay\">01:00:01</d:PropertyTimeOfDay>\n" +
+ " </d:PropertyComp>\n" +
+ " </m:properties>\n" +
+ " </a:content>\n" +
"</a:entry>";
- XMLAssert.assertXMLEqual(expected, resultString);
+ checkXMLEqual(expected, resultString);
}
@Test
public void entityMixPrimCollComp() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp");
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
+ long currentTimeMillis = System.currentTimeMillis();
InputStream result = serializer.entity(metadata, edmEntitySet.getEntityType(), entity,
EntitySerializerOptions.with()
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
.build()).getContent();
final String resultString = IOUtils.toString(result);
- final String expectedResult = "<?xml version='1.0' encoding='UTF-8'?>\n" +
- "<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\"\n" +
- " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
- " xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" \n" +
- " m:context=\"$metadata#ESMixPrimCollComp/$entity\"\n" +
- " m:metadata-etag=\"WmetadataETag\">\n" +
- " <a:id>ESMixPrimCollComp(32767)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- " <a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESMixPrimCollComp(32767)\"/>\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETMixPrimCollComp\" />\n" +
- " <a:content type=\"application/xml\">\n" +
- " <m:properties>\n" +
- " <d:PropertyInt16 m:type=\"Int16\">32767</d:PropertyInt16>\n" +
- " <d:CollPropertyString m:type=\"#Collection(String)\">\n" +
- " <m:element>Employee1@company.example</m:element>\n" +
- " <m:element>Employee2@company.example</m:element>\n" +
- " <m:element>Employee3@company.example</m:element>\n" +
- " </d:CollPropertyString>\n" +
- " <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" +
- " <d:PropertyInt16 m:type=\"Int16\">111</d:PropertyInt16>\n" +
- " <d:PropertyString>TEST A</d:PropertyString>\n" +
- " </d:PropertyComp>\n" +
- " <d:CollPropertyComp m:type=\"#Collection(olingo.odata.test1.CTTwoPrim)\">\n" +
- " <m:element>\n" +
- " <d:PropertyInt16 m:type=\"Int16\">123</d:PropertyInt16>\n" +
- " <d:PropertyString>TEST 1</d:PropertyString>\n" +
- " </m:element>\n" +
- " <m:element>\n" +
- " <d:PropertyInt16 m:type=\"Int16\">456</d:PropertyInt16>\n" +
- " <d:PropertyString>TEST 2</d:PropertyString>\n" +
- " </m:element>\n" +
- " <m:element>\n" +
- " <d:PropertyInt16 m:type=\"Int16\">789</d:PropertyInt16>\n" +
- " <d:PropertyString>TEST 3</d:PropertyString>\n" +
- " </m:element>\n" +
- " </d:CollPropertyComp>\n" +
- " </m:properties>\n" +
- " </a:content>\n" +
- "</a:entry>\n";
+ final String expectedResult = "<?xml version='1.0' encoding='UTF-8'?>\n" +
+ "<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\"\n" +
+ " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
+ " xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" \n" +
+ " m:context=\"$metadata#ESMixPrimCollComp/$entity\"\n" +
+ " m:metadata-etag=\"WmetadataETag\">\n" +
+ " <a:id>ESMixPrimCollComp(32767)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ " <a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESMixPrimCollComp(32767)\"/>\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETMixPrimCollComp\" />\n" +
+ " <a:content type=\"application/xml\">\n" +
+ " <m:properties>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">32767</d:PropertyInt16>\n" +
+ " <d:CollPropertyString m:type=\"#Collection(String)\">\n" +
+ " <m:element>Employee1@company.example</m:element>\n" +
+ " <m:element>Employee2@company.example</m:element>\n" +
+ " <m:element>Employee3@company.example</m:element>\n" +
+ " </d:CollPropertyString>\n" +
+ " <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">111</d:PropertyInt16>\n" +
+ " <d:PropertyString>TEST A</d:PropertyString>\n" +
+ " </d:PropertyComp>\n" +
+ " <d:CollPropertyComp m:type=\"#Collection(olingo.odata.test1.CTTwoPrim)\">\n" +
+ " <m:element>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">123</d:PropertyInt16>\n" +
+ " <d:PropertyString>TEST 1</d:PropertyString>\n" +
+ " </m:element>\n" +
+ " <m:element>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">456</d:PropertyInt16>\n" +
+ " <d:PropertyString>TEST 2</d:PropertyString>\n" +
+ " </m:element>\n" +
+ " <m:element>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">789</d:PropertyInt16>\n" +
+ " <d:PropertyString>TEST 3</d:PropertyString>\n" +
+ " </m:element>\n" +
+ " </d:CollPropertyComp>\n" +
+ " </m:properties>\n" +
+ " </a:content>\n" +
+ "</a:entry>\n";
XMLAssert.assertXMLEqual(expectedResult, resultString);
}
@@ -507,36 +524,38 @@ public class ODataXmlSerializerTest {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp");
Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
entity.getProperties().retainAll(Arrays.asList(entity.getProperties().get(0)));
- final String resultString = IOUtils.toString(serializer.entity(metadata, edmEntitySet.getEntityType(),
+ long currentTimeMillis = System.currentTimeMillis();
+ InputStream content = serializer.entity(metadata, edmEntitySet.getEntityType(),
entity,
EntitySerializerOptions.with()
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
- .build()).getContent());
- final String expectedResult = "<?xml version='1.0' encoding='UTF-8'?>\n" +
- "<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\"\n" +
- " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
+ .build()).getContent();
+ final String resultString = IOUtils.toString(content);
+ final String expectedResult = "<?xml version='1.0' encoding='UTF-8'?>\n" +
+ "<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\"\n" +
+ " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" "
- + "m:context=\"$metadata#ESMixPrimCollComp/$entity\"\n" +
- " m:metadata-etag=\"WmetadataETag\">\n" +
- " <a:id>ESMixPrimCollComp(32767)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- " <a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESMixPrimCollComp(32767)\"/>\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETMixPrimCollComp\" />\n" +
- " <a:content type=\"application/xml\">\n" +
- " <m:properties>\n" +
- " <d:PropertyInt16 m:type=\"Int16\">32767</d:PropertyInt16>\n" +
- " <d:CollPropertyString m:null=\"true\" />\n" +
- " <d:PropertyComp m:null=\"true\" />\n" +
- " <d:CollPropertyComp m:null=\"true\" />\n" +
- " </m:properties>\n" +
- " </a:content>\n" +
+ + "m:context=\"$metadata#ESMixPrimCollComp/$entity\"\n" +
+ " m:metadata-etag=\"WmetadataETag\">\n" +
+ " <a:id>ESMixPrimCollComp(32767)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ " <a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESMixPrimCollComp(32767)\"/>\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETMixPrimCollComp\" />\n" +
+ " <a:content type=\"application/xml\">\n" +
+ " <m:properties>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">32767</d:PropertyInt16>\n" +
+ " <d:CollPropertyString m:null=\"true\" />\n" +
+ " <d:PropertyComp m:null=\"true\" />\n" +
+ " <d:CollPropertyComp m:null=\"true\" />\n" +
+ " </m:properties>\n" +
+ " </a:content>\n" +
"</a:entry>";
XMLAssert.assertXMLEqual(expectedResult, resultString);
}
@@ -573,33 +592,35 @@ public class ODataXmlSerializerTest {
public void entityMedia() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMedia");
final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
- final String resultString = IOUtils.toString(serializer.entity(metadata, edmEntitySet.getEntityType(),
+ long currentTimeMillis = System.currentTimeMillis();
+ InputStream content = serializer.entity(metadata, edmEntitySet.getEntityType(),
entity,
EntitySerializerOptions.with()
.contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
- .build()).getContent());
- final String expectedResult = "<?xml version='1.0' encoding='UTF-8'?>\n" +
- "<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\"\n" +
- " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
+ .build()).getContent();
+ final String resultString = IOUtils.toString(content);
+ final String expectedResult = "<?xml version='1.0' encoding='UTF-8'?>\n" +
+ "<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\"\n" +
+ " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" " +
- " m:context=\"$metadata#ESMedia/$entity\"\n" +
- " m:metadata-etag=\"WmetadataETag\">\n" +
- " <a:id>ESMedia(1)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- " <a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESMedia(1)\"/>\n" +
+ " m:context=\"$metadata#ESMedia/$entity\"\n" +
+ " m:metadata-etag=\"WmetadataETag\">\n" +
+ " <a:id>ESMedia(1)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ " <a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESMedia(1)\"/>\n" +
" <a:content type=\"image/svg+xml\" src=\"ESMedia(1)/$value\" />\n" +
" <a:link rel=\"edit-media\" title=\"ESMedia\" href=\"ESMedia(1)/$value\"/>\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETMedia\" />\n" +
- " <m:properties>\n" +
- " <d:PropertyInt16 m:type=\"Int16\">1</d:PropertyInt16>\n" +
- " </m:properties>\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETMedia\" />\n" +
+ " <m:properties>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">1</d:PropertyInt16>\n" +
+ " </m:properties>\n" +
"</a:entry>";
XMLAssert.assertXMLEqual(expectedResult, resultString);
}
@@ -608,92 +629,94 @@ public class ODataXmlSerializerTest {
public void entitySetMedia() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMedia");
final EntityCollection entitySet = data.readAll(edmEntitySet);
- final String resultString = IOUtils.toString(serializer.entityCollection(metadata,
+ long currentTimeMillis = System.currentTimeMillis();
+ InputStream content = serializer.entityCollection(metadata,
edmEntitySet.getEntityType(), entitySet,
EntityCollectionSerializerOptions.with()
.contextURL(ContextURL.with().entitySet(edmEntitySet).build())
.setId("http://host/svc/ESMedia")
- .build()).getContent());
-
- final String expectedResult = "<?xml version='1.0' encoding='UTF-8'?>\n" +
- "<a:feed xmlns:a=\"http://www.w3.org/2005/Atom\"\n" +
- " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
- " xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" m:context=\"$metadata#ESMedia\"\n" +
- " m:metadata-etag=\"WmetadataETag\">\n" +
- " <a:id>http://host/svc/ESMedia</a:id>\n" +
- " <a:entry>\n" +
- " <a:id>ESMedia(1)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- " <a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESMedia(1)\"/>\n" +
+ .build()).getContent();
+ final String resultString = IOUtils.toString(content);
+
+ final String expectedResult = "<?xml version='1.0' encoding='UTF-8'?>\n" +
+ "<a:feed xmlns:a=\"http://www.w3.org/2005/Atom\"\n" +
+ " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
+ " xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" m:context=\"$metadata#ESMedia\"\n" +
+ " m:metadata-etag=\"WmetadataETag\">\n" +
+ " <a:id>http://host/svc/ESMedia</a:id>\n" +
+ " <a:entry>\n" +
+ " <a:id>ESMedia(1)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ " <a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESMedia(1)\"/>\n" +
" <a:content type=\"image/svg+xml\" src=\"ESMedia(1)/$value\" />\n" +
" <a:link rel=\"edit-media\" title=\"ESMedia\" href=\"ESMedia(1)/$value\"/>\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETMedia\" />\n" +
- " <m:properties>\n" +
- " <d:PropertyInt16 m:type=\"Int16\">1</d:PropertyInt16>\n" +
- " </m:properties>\n" +
- " </a:entry>\n" +
- " <a:entry>\n" +
- " <a:id>ESMedia(2)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- " <a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESMedia(2)\"/>\n" +
- " <a:content type=\"image/svg+xml\" src=\"ESMedia(2)/$value\" />\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETMedia\" />\n" +
+ " <m:properties>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">1</d:PropertyInt16>\n" +
+ " </m:properties>\n" +
+ " </a:entry>\n" +
+ " <a:entry>\n" +
+ " <a:id>ESMedia(2)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ " <a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESMedia(2)\"/>\n" +
+ " <a:content type=\"image/svg+xml\" src=\"ESMedia(2)/$value\" />\n" +
" <a:link rel=\"edit-media\" title=\"ESMedia\" href=\"ESMedia(2)/$value\"/>\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETMedia\" />\n" +
- " <m:properties>\n" +
- " <d:PropertyInt16 m:type=\"Int16\">2</d:PropertyInt16>\n" +
- " </m:properties>\n" +
- " </a:entry>\n" +
- " <a:entry>\n" +
- " <a:id>ESMedia(3)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- " <a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESMedia(3)\"/>\n" +
- " <a:content type=\"image/svg+xml\" src=\"ESMedia(3)/$value\" />\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETMedia\" />\n" +
+ " <m:properties>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">2</d:PropertyInt16>\n" +
+ " </m:properties>\n" +
+ " </a:entry>\n" +
+ " <a:entry>\n" +
+ " <a:id>ESMedia(3)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ " <a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESMedia(3)\"/>\n" +
+ " <a:content type=\"image/svg+xml\" src=\"ESMedia(3)/$value\" />\n" +
" <a:link rel=\"edit-media\" title=\"ESMedia\" href=\"ESMedia(3)/$value\"/>\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETMedia\" />\n" +
- " <m:properties>\n" +
- " <d:PropertyInt16 m:type=\"Int16\">3</d:PropertyInt16>\n" +
- " </m:properties>\n" +
- " </a:entry>\n" +
- " <a:entry>\n" +
- " <a:id>ESMedia(4)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- " <a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESMedia(4)\"/>\n" +
- " <a:content type=\"image/svg+xml\" src=\"ESMedia(4)/$value\" />\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETMedia\" />\n" +
+ " <m:properties>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">3</d:PropertyInt16>\n" +
+ " </m:properties>\n" +
+ " </a:entry>\n" +
+ " <a:entry>\n" +
+ " <a:id>ESMedia(4)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ " <a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESMedia(4)\"/>\n" +
+ " <a:content type=\"image/svg+xml\" src=\"ESMedia(4)/$value\" />\n" +
" <a:link rel=\"edit-media\" title=\"ESMedia\" href=\"ESMedia(4)/$value\"/>\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETMedia\" />\n" +
- " <m:properties>\n" +
- " <d:PropertyInt16 m:type=\"Int16\">4</d:PropertyInt16>\n" +
- " </m:properties>\n" +
- " </a:entry>\n" +
- "</a:feed>\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETMedia\" />\n" +
+ " <m:properties>\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">4</d:PropertyInt16>\n" +
+ " </m:properties>\n" +
+ " </a:entry>\n" +
+ "</a:feed>\n" +
"";
XMLAssert.assertXMLEqual(expectedResult, resultString);
}
@@ -702,136 +725,138 @@ public class ODataXmlSerializerTest {
public void primitiveValuesAllNull() throws Exception {
final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllNullable");
final EntityCollection entitySet = data.readAll(edmEntitySet);
- final String resultString = IOUtils.toString(serializer.entityCollection(metadata,
+ long currentTimeMillis = System.currentTimeMillis();
+ InputStream content = serializer.entityCollection(metadata,
edmEntitySet.getEntityType(), entitySet,
- EntityCollectionSerializerOptions.with()
- .contextURL(ContextURL.with().serviceRoot(URI.create("http://host/svc"))
- .entitySet(edmEntitySet).build())
- .setId("http://host/svc/ESAllNullable")
- .build()).getContent());
- String expected = "<?xml version='1.0' encoding='UTF-8'?>\n" +
+ EntityCollectionSerializerOptions.with()
+ .contextURL(ContextURL.with().serviceRoot(URI.create("http://host/svc"))
+ .entitySet(edmEntitySet).build())
+ .setId("http://host/svc/ESAllNullable")
+ .build()).getContent();
+ final String resultString = IOUtils.toString(content);
+ String expected = "<?xml version='1.0' encoding='UTF-8'?>\n" +
"<a:feed xmlns:a=\"http://www.w3.org/2005/Atom\" "
- + "xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
+ + "xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" "
- + "m:context=\"http://host/svc$metadata#ESAllNullable\"\n" +
- " m:metadata-etag=\"WmetadataETag\">\n" +
- " <a:id>http://host/svc/ESAllNullable</a:id>\n" +
- " <a:entry>\n" +
- " <a:id>ESAllNullable(1)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- " <a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESAllNullable(1)\" />\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETAllNullable\" />\n" +
- " <a:content type=\"application/xml\">\n" +
- " <m:properties>\n" +
- " <d:PropertyKey m:type=\"Int16\">1</d:PropertyKey>\n" +
- " <d:PropertyInt16 m:null=\"true\" />\n" +
- " <d:PropertyString m:null=\"true\" />\n" +
- " <d:PropertyBoolean m:null=\"true\" />\n" +
- " <d:PropertyByte m:null=\"true\" />\n" +
- " <d:PropertySByte m:null=\"true\" />\n" +
- " <d:PropertyInt32 m:null=\"true\" />\n" +
- " <d:PropertyInt64 m:null=\"true\" />\n" +
- " <d:PropertySingle m:null=\"true\" />\n" +
- " <d:PropertyDouble m:null=\"true\" />\n" +
- " <d:PropertyDecimal m:null=\"true\" />\n" +
- " <d:PropertyBinary m:null=\"true\" />\n" +
- " <d:PropertyDate m:null=\"true\" />\n" +
- " <d:PropertyDateTimeOffset m:null=\"true\" />\n" +
- " <d:PropertyDuration m:null=\"true\" />\n" +
- " <d:PropertyGuid m:null=\"true\" />\n" +
- " <d:PropertyTimeOfDay m:null=\"true\" />\n" +
- " <d:CollPropertyString m:type=\"#Collection(String)\">\n" +
- " <m:element>spiderman@comic.com</m:element>\n" +
- " <m:element d:null=\"true\" />\n" +
- " <m:element>spidergirl@comic.com</m:element>\n" +
- " </d:CollPropertyString>\n" +
- " <d:CollPropertyBoolean m:type=\"#Collection(Boolean)\">\n" +
- " <m:element>true</m:element>\n" +
- " <m:element d:null=\"true\" />\n" +
- " <m:element>false</m:element>\n" +
- " </d:CollPropertyBoolean>\n" +
- " <d:CollPropertyByte m:type=\"#Collection(Byte)\">\n" +
- " <m:element>50</m:element>\n" +
- " <m:element d:null=\"true\" />\n" +
- " <m:element>249</m:element>\n" +
- " </d:CollPropertyByte>\n" +
- " <d:CollPropertySByte m:type=\"#Collection(SByte)\">\n" +
- " <m:element>-120</m:element>\n" +
- " <m:element d:null=\"true\" />\n" +
- " <m:element>126</m:element>\n" +
- " </d:CollPropertySByte>\n" +
- " <d:CollPropertyInt16 m:type=\"#Collection(Int16)\">\n" +
- " <m:element>1000</m:element>\n" +
- " <m:element d:null=\"true\" />\n" +
- " <m:element>30112</m:element>\n" +
- " </d:CollPropertyInt16>\n" +
- " <d:CollPropertyInt32 m:type=\"#Collection(Int32)\">\n" +
- " <m:element>23232323</m:element>\n" +
- " <m:element d:null=\"true\" />\n" +
- " <m:element>10000001</m:element>\n" +
- " </d:CollPropertyInt32>\n" +
- " <d:CollPropertyInt64 m:type=\"#Collection(Int64)\">\n" +
- " <m:element>929292929292</m:element>\n" +
- " <m:element d:null=\"true\" />\n" +
- " <m:element>444444444444</m:element>\n" +
- " </d:CollPropertyInt64>\n" +
- " <d:CollPropertySingle m:type=\"#Collection(Single)\">\n" +
- " <m:element>1790.0</m:element>\n" +
- " <m:element d:null=\"true\" />\n" +
- " <m:element>3210.0</m:element>\n" +
- " </d:CollPropertySingle>\n" +
- " <d:CollPropertyDouble m:type=\"#Collection(Double)\">\n" +
- " <m:element>-17900.0</m:element>\n" +
- " <m:element d:null=\"true\" />\n" +
- " <m:element>3210.0</m:element>\n" +
- " </d:CollPropertyDouble>\n" +
- " <d:CollPropertyDecimal m:type=\"#Collection(Decimal)\">\n" +
- " <m:element>12</m:element>\n" +
- " <m:element d:null=\"true\" />\n" +
- " <m:element>1234</m:element>\n" +
- " </d:CollPropertyDecimal>\n" +
- " <d:CollPropertyBinary m:type=\"#Collection(Binary)\">\n" +
- " <m:element>q83v</m:element>\n" +
- " <m:element d:null=\"true\" />\n" +
- " <m:element>VGeJ</m:element>\n" +
- " </d:CollPropertyBinary>\n" +
- " <d:CollPropertyDate m:type=\"#Collection(Date)\">\n" +
- " <m:element>1958-12-03</m:element>\n" +
- " <m:element d:null=\"true\" />\n" +
- " <m:element>2013-06-25</m:element>\n" +
- " </d:CollPropertyDate>\n" +
- " <d:CollPropertyDateTimeOffset m:type=\"#Collection(DateTimeOffset)\">\n" +
- " <m:element>2015-08-12T03:08:34Z</m:element>\n" +
- " <m:element d:null=\"true\" />\n" +
- " <m:element>1948-02-17T09:09:09Z</m:element>\n" +
- " </d:CollPropertyDateTimeOffset>\n" +
- " <d:CollPropertyDuration m:type=\"#Collection(Duration)\">\n" +
- " <m:element>PT13S</m:element>\n" +
- " <m:element d:null=\"true\" />\n" +
- " <m:element>PT1H0S</m:element>\n" +
- " </d:CollPropertyDuration>\n" +
- " <d:CollPropertyGuid m:type=\"#Collection(Guid)\">\n" +
- " <m:element>ffffff67-89ab-cdef-0123-456789aaaaaa</m:element>\n" +
- " <m:element d:null=\"true\" />\n" +
- " <m:element>cccccc67-89ab-cdef-0123-456789cccccc</m:element>\n" +
- " </d:CollPropertyGuid>\n" +
- " <d:CollPropertyTimeOfDay m:type=\"#Collection(TimeOfDay)\">\n" +
- " <m:element>04:14:13</m:element>\n" +
- " <m:element d:null=\"true\" />\n" +
- " <m:element>00:37:13</m:element>\n" +
- " </d:CollPropertyTimeOfDay>\n" +
- " </m:properties>\n" +
- " </a:content>\n" +
- " </a:entry>\n" +
+ + "m:context=\"http://host/svc$metadata#ESAllNullable\"\n" +
+ " m:metadata-etag=\"WmetadataETag\">\n" +
+ " <a:id>http://host/svc/ESAllNullable</a:id>\n" +
+ " <a:entry>\n" +
+ " <a:id>ESAllNullable(1)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ " <a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESAllNullable(1)\" />\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETAllNullable\" />\n" +
+ " <a:content type=\"application/xml\">\n" +
+ " <m:properties>\n" +
+ " <d:PropertyKey m:type=\"Int16\">1</d:PropertyKey>\n" +
+ " <d:PropertyInt16 m:null=\"true\" />\n" +
+ " <d:PropertyString m:null=\"true\" />\n" +
+ " <d:PropertyBoolean m:null=\"true\" />\n" +
+ " <d:PropertyByte m:null=\"true\" />\n" +
+ " <d:PropertySByte m:null=\"true\" />\n" +
+ " <d:PropertyInt32 m:null=\"true\" />\n" +
+ " <d:PropertyInt64 m:null=\"true\" />\n" +
+ " <d:PropertySingle m:null=\"true\" />\n" +
+ " <d:PropertyDouble m:null=\"true\" />\n" +
+ " <d:PropertyDecimal m:null=\"true\" />\n" +
+ " <d:PropertyBinary m:null=\"true\" />\n" +
+ " <d:PropertyDate m:null=\"true\" />\n" +
+ " <d:PropertyDateTimeOffset m:null=\"true\" />\n" +
+ " <d:PropertyDuration m:null=\"true\" />\n" +
+ " <d:PropertyGuid m:null=\"true\" />\n" +
+ " <d:PropertyTimeOfDay m:null=\"true\" />\n" +
+ " <d:CollPropertyString m:type=\"#Collection(String)\">\n" +
+ " <m:element>spiderman@comic.com</m:element>\n" +
+ " <m:element d:null=\"true\" />\n" +
+ " <m:element>spidergirl@comic.com</m:element>\n" +
+ " </d:CollPropertyString>\n" +
+ " <d:CollPropertyBoolean m:type=\"#Collection(Boolean)\">\n" +
+ " <m:element>true</m:element>\n" +
+ " <m:element d:null=\"true\" />\n" +
+ " <m:element>false</m:element>\n" +
+ " </d:CollPropertyBoolean>\n" +
+ " <d:CollPropertyByte m:type=\"#Collection(Byte)\">\n" +
+ " <m:element>50</m:element>\n" +
+ " <m:element d:null=\"true\" />\n" +
+ " <m:element>249</m:element>\n" +
+ " </d:CollPropertyByte>\n" +
+ " <d:CollPropertySByte m:type=\"#Collection(SByte)\">\n" +
+ " <m:element>-120</m:element>\n" +
+ " <m:element d:null=\"true\" />\n" +
+ " <m:element>126</m:element>\n" +
+ " </d:CollPropertySByte>\n" +
+ " <d:CollPropertyInt16 m:type=\"#Collection(Int16)\">\n" +
+ " <m:element>1000</m:element>\n" +
+ " <m:element d:null=\"true\" />\n" +
+ " <m:element>30112</m:element>\n" +
+ " </d:CollPropertyInt16>\n" +
+ " <d:CollPropertyInt32 m:type=\"#Collection(Int32)\">\n" +
+ " <m:element>23232323</m:element>\n" +
+ " <m:element d:null=\"true\" />\n" +
+ " <m:element>10000001</m:element>\n" +
+ " </d:CollPropertyInt32>\n" +
+ " <d:CollPropertyInt64 m:type=\"#Collection(Int64)\">\n" +
+ " <m:element>929292929292</m:element>\n" +
+ " <m:element d:null=\"true\" />\n" +
+ " <m:element>444444444444</m:element>\n" +
+ " </d:CollPropertyInt64>\n" +
+ " <d:CollPropertySingle m:type=\"#Collection(Single)\">\n" +
+ " <m:element>1790.0</m:element>\n" +
+ " <m:element d:null=\"true\" />\n" +
+ " <m:element>3210.0</m:element>\n" +
+ " </d:CollPropertySingle>\n" +
+ " <d:CollPropertyDouble m:type=\"#Collection(Double)\">\n" +
+ " <m:element>-17900.0</m:element>\n" +
+ " <m:element d:null=\"true\" />\n" +
+ " <m:element>3210.0</m:element>\n" +
+ " </d:CollPropertyDouble>\n" +
+ " <d:CollPropertyDecimal m:type=\"#Collection(Decimal)\">\n" +
+ " <m:element>12</m:element>\n" +
+ " <m:element d:null=\"true\" />\n" +
+ " <m:element>1234</m:element>\n" +
+ " </d:CollPropertyDecimal>\n" +
+ " <d:CollPropertyBinary m:type=\"#Collection(Binary)\">\n" +
+ " <m:element>q83v</m:element>\n" +
+ " <m:element d:null=\"true\" />\n" +
+ " <m:element>VGeJ</m:element>\n" +
+ " </d:CollPropertyBinary>\n" +
+ " <d:CollPropertyDate m:type=\"#Collection(Date)\">\n" +
+ " <m:element>1958-12-03</m:element>\n" +
+ " <m:element d:null=\"true\" />\n" +
+ " <m:element>2013-06-25</m:element>\n" +
+ " </d:CollPropertyDate>\n" +
+ " <d:CollPropertyDateTimeOffset m:type=\"#Collection(DateTimeOffset)\">\n" +
+ " <m:element>2015-08-12T03:08:34Z</m:element>\n" +
+ " <m:element d:null=\"true\" />\n" +
+ " <m:element>1948-02-17T09:09:09Z</m:element>\n" +
+ " </d:CollPropertyDateTimeOffset>\n" +
+ " <d:CollPropertyDuration m:type=\"#Collection(Duration)\">\n" +
+ " <m:element>PT13S</m:element>\n" +
+ " <m:element d:null=\"true\" />\n" +
+ " <m:element>PT1H0S</m:element>\n" +
+ " </d:CollPropertyDuration>\n" +
+ " <d:CollPropertyGuid m:type=\"#Collection(Guid)\">\n" +
+ " <m:element>ffffff67-89ab-cdef-0123-456789aaaaaa</m:element>\n" +
+ " <m:element d:null=\"true\" />\n" +
+ " <m:element>cccccc67-89ab-cdef-0123-456789cccccc</m:element>\n" +
+ " </d:CollPropertyGuid>\n" +
+ " <d:CollPropertyTimeOfDay m:type=\"#Collection(TimeOfDay)\">\n" +
+ " <m:element>04:14:13</m:element>\n" +
+ " <m:element d:null=\"true\" />\n" +
+ " <m:element>00:37:13</m:element>\n" +
+ " </d:CollPropertyTimeOfDay>\n" +
+ " </m:properties>\n" +
+ " </a:content>\n" +
+ " </a:entry>\n" +
"</a:feed>";
- XMLAssert.assertXMLEqual(expected, resultString);
+ checkXMLEqual(expected, resultString);
}
@Test
@@ -843,6 +868,7 @@ public class ODataXmlSerializerTest {
final SelectItem selectItem2 = ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertyBoolean");
final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(
selectItem1, selectItem2, selectItem2));
+ long currentTimeMillis = System.currentTimeMillis();
InputStream result = serializer
.entity(metadata, entityType, entity,
EntitySerializerOptions.with()
@@ -852,37 +878,37 @@ public class ODataXmlSerializerTest {
.select(select)
.build()).getContent();
final String resultString = IOUtils.toString(result);
- final String expectedResult = "<?xml version='1.0' encoding='UTF-8'?>\n" +
- "<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\"\n" +
- " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
+ final String expectedResult = "<?xml version='1.0' encoding='UTF-8'?>\n" +
+ "<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\"\n" +
+ " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" " +
- " m:context=\"$metadata#ESAllPrim(PropertyBoolean,PropertyDate)/$entity\"\n" +
- " m:metadata-etag=\"WmetadataETag\">\n" +
- " <a:id>ESAllPrim(32767)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- " <a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESAllPrim(32767)\"/>\n" +
- " <a:link\n" +
- " rel=\"http://docs.oasis-open.org/odata/ns/related/NavPropertyETTwoPrimOne\"\n" +
- " type=\"application/atom+xml;type=entry\" title=\"NavPropertyETTwoPrimOne\"\n" +
+ " m:context=\"$metadata#ESAllPrim(PropertyBoolean,PropertyDate)/$entity\"\n" +
+ " m:metadata-etag=\"WmetadataETag\">\n" +
+ " <a:id>ESAllPrim(32767)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ " <a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESAllPrim(32767)\"/>\n" +
+ " <a:link\n" +
+ " rel=\"http://docs.oasis-open.org/odata/ns/related/NavPropertyETTwoPrimOne\"\n" +
+ " type=\"application/atom+xml;type=entry\" title=\"NavPropertyETTwoPrimOne\"\n" +
" href=\"ESTwoPrim(32767)\" />\n" +
- " <a:link\n" +
- " rel=\"http://docs.oasis-open.org/odata/ns/related/NavPropertyETTwoPrimMany\"\n" +
- " type=\"application/atom+xml;type=feed\" title=\"NavPropertyETTwoPrimMany\"\n" +
- " href=\"ESAllPrim(32767)/NavPropertyETTwoPrimMany\" />\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETAllPrim\" />\n" +
- " <a:content type=\"application/xml\">\n" +
- " <m:properties>\n" +
- " <d:PropertyBoolean m:type=\"Boolean\">true</d:PropertyBoolean>\n" +
- " <d:PropertyDate m:type=\"Date\">2012-12-03</d:PropertyDate>\n" +
- " </m:properties>\n" +
- " </a:content>\n" +
+ " <a:link\n" +
+ " rel=\"http://docs.oasis-open.org/odata/ns/related/NavPropertyETTwoPrimMany\"\n" +
+ " type=\"application/atom+xml;type=feed\" title=\"NavPropertyETTwoPrimMany\"\n" +
+ " href=\"ESAllPrim(32767)/NavPropertyETTwoPrimMany\" />\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETAllPrim\" />\n" +
+ " <a:content type=\"application/xml\">\n" +
+ " <m:properties>\n" +
+ " <d:PropertyBoolean m:type=\"Boolean\">true</d:PropertyBoolean>\n" +
+ " <d:PropertyDate m:type=\"Date\">2012-12-03</d:PropertyDate>\n" +
+ " </m:properties>\n" +
+ " </a:content>\n" +
"</a:entry>";
XMLAssert.assertXMLEqual(expectedResult, resultString);
}
@@ -894,6 +920,7 @@ public class ODataXmlSerializerTest {
final EntityCollection entitySet = data.readAll(edmEntitySet);
final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(
ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertyComp", "PropertyComp", "PropertyString")));
+ long currentTimeMillis = System.currentTimeMillis();
InputStream result = serializer
.entityCollection(metadata, entityType, entitySet,
EntityCollectionSerializerOptions.with()
@@ -904,59 +931,59 @@ public class ODataXmlSerializerTest {
.select(select)
.build()).getContent();
final String resultString = IOUtils.toString(result);
- final String expected = "<?xml version='1.0' encoding='UTF-8'?>\n" +
- "<a:feed xmlns:a=\"http://www.w3.org/2005/Atom\"\n" +
- " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
- " xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\"\n" +
- " m:context=\"$metadata#ESCompComp(PropertyComp/PropertyComp/PropertyString)\"\n" +
- " m:metadata-etag=\"WmetadataETag\">\n" +
- " <a:id>http://host/svc/ESCompComp</a:id>\n" +
- " <a:entry>\n" +
- " <a:id>ESCompComp(1)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- "<a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESCompComp(1)\"/>\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETCompComp\" />\n" +
- " <a:content type=\"application/xml\">\n" +
- " <m:properties>\n" +
- " <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompComp\">\n" +
- " <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" +
- " <d:PropertyString>String 1</d:PropertyString>\n" +
- " </d:PropertyComp>\n" +
- " </d:PropertyComp>\n" +
- " </m:properties>\n" +
- " </a:content>\n" +
- " </a:entry>\n" +
- " <a:entry>\n" +
- " <a:id>ESCompComp(2)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- "<a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESCompComp(2)\"/>\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETCompComp\" />\n" +
- " <a:content type=\"application/xml\">\n" +
- " <m:properties>\n" +
- " <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompComp\">\n" +
- " <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" +
- " <d:PropertyString>String 2</d:PropertyString>\n" +
- " </d:PropertyComp>\n" +
- " </d:PropertyComp>\n" +
- " </m:properties>\n" +
- " </a:content>\n" +
- " </a:entry>\n" +
- "</a:feed>\n";
- XMLAssert.assertXMLEqual(expected, resultString);
+ final String expected = "<?xml version='1.0' encoding='UTF-8'?>\n" +
+ "<a:feed xmlns:a=\"http://www.w3.org/2005/Atom\"\n" +
+ " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
+ " xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\"\n" +
+ " m:context=\"$metadata#ESCompComp(PropertyComp/PropertyComp/PropertyString)\"\n" +
+ " m:metadata-etag=\"WmetadataETag\">\n" +
+ " <a:id>http://host/svc/ESCompComp</a:id>\n" +
+ " <a:entry>\n" +
+ " <a:id>ESCompComp(1)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ "<a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESCompComp(1)\"/>\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETCompComp\" />\n" +
+ " <a:content type=\"application/xml\">\n" +
+ " <m:properties>\n" +
+ " <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompComp\">\n" +
+ " <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" +
+ " <d:PropertyString>String 1</d:PropertyString>\n" +
+ " </d:PropertyComp>\n" +
+ " </d:PropertyComp>\n" +
+ " </m:properties>\n" +
+ " </a:content>\n" +
+ " </a:entry>\n" +
+ " <a:entry>\n" +
+ " <a:id>ESCompComp(2)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ "<a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESCompComp(2)\"/>\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETCompComp\" />\n" +
+ " <a:content type=\"application/xml\">\n" +
+ " <m:properties>\n" +
+ " <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompComp\">\n" +
+ " <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" +
+ " <d:PropertyString>String 2</d:PropertyString>\n" +
+ " </d:PropertyComp>\n" +
+ " </d:PropertyComp>\n" +
+ " </m:properties>\n" +
+ " </a:content>\n" +
+ " </a:entry>\n" +
+ "</a:feed>\n";
+ checkXMLEqual(expected, resultString);
}
@Test
@@ -967,7 +994,8 @@ public class ODataXmlSerializerTest {
final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(
ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertyComp", "PropertyComp", "PropertyString"),
ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertyComp", "PropertyComp")));
- final String resultString = IOUtils.toString(serializer
+ long currentTimeMillis = System.currentTimeMillis();
+ InputStream inputStream = serializer
.entityCollection(metadata, entityType, entitySet,
EntityCollectionSerializerOptions.with()
.contextURL(ContextURL.with().entitySet(edmEntitySet)
@@ -975,62 +1003,63 @@ public class ODataXmlSerializerTest {
.build())
.setId("http://host/svc/ESCompComp")
.select(select)
- .build()).getContent());
- String expected = "<?xml version='1.0' encoding='UTF-8'?>\n" +
- "<a:feed xmlns:a=\"http://www.w3.org/2005/Atom\"\n" +
- " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
- " xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" \n" +
- " m:context=\"$metadata#ESCompComp(PropertyComp/PropertyComp)\"\n" +
- " m:metadata-etag=\"WmetadataETag\">\n" +
- " <a:id>http://host/svc/ESCompComp</a:id>\n" +
- " <a:entry>\n" +
- " <a:id>ESCompComp(1)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- " <a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESCompComp(1)\"/>\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETCompComp\" />\n" +
- " <a:content type=\"application/xml\">\n" +
- " <m:properties>\n" +
- " <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompComp\">\n" +
- " <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" +
- " <d:PropertyInt16 m:type=\"Int16\">123</d:PropertyInt16>\n" +
- " <d:PropertyString>String 1</d:PropertyString>\n" +
- " </d:PropertyComp>\n" +
- " </d:PropertyComp>\n" +
- " </m:properties>\n" +
- " </a:content>\n" +
- " </a:entry>\n" +
- " <a:entry>\n" +
- " <a:id>ESCompComp(2)</a:id>\n" +
- " <a:title />\n" +
- " <a:summary />\n" +
- " <a:updated>"+new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis()))+"</a:updated>" +
- " <a:author>\n" +
- " <a:name />\n" +
- " </a:author>\n" +
- " <a:link rel=\"edit\" href=\"ESCompComp(2)\"/>\n" +
- " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
- " term=\"#olingo.odata.test1.ETCompComp\" />\n" +
- " <a:content type=\"application/xml\">\n" +
- " <m:properties>\n" +
- " <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompComp\">\n" +
- " <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" +
- " <d:PropertyInt16 m:type=\"Int16\">987</d:PropertyInt16>\n" +
- " <d:PropertyString>String 2</d:PropertyString>\n" +
- " </d:PropertyComp>\n" +
- " </d:PropertyComp>\n" +
- " </m:properties>\n" +
- " </a:content>\n" +
- " </a:entry>\n" +
+ .build()).getContent();
+ final String resultString = IOUtils.toString(inputStream);
+ String expected = "<?xml version='1.0' encoding='UTF-8'?>\n" +
+ "<a:feed xmlns:a=\"http://www.w3.org/2005/Atom\"\n" +
+ " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" +
+ " xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" \n" +
+ " m:context=\"$metadata#ESCompComp(PropertyComp/PropertyComp)\"\n" +
+ " m:metadata-etag=\"WmetadataETag\">\n" +
+ " <a:id>http://host/svc/ESCompComp</a:id>\n" +
+ " <a:entry>\n" +
+ " <a:id>ESCompComp(1)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ " <a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESCompComp(1)\"/>\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETCompComp\" />\n" +
+ " <a:content type=\"application/xml\">\n" +
+ " <m:properties>\n" +
+ " <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompComp\">\n" +
+ " <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">123</d:PropertyInt16>\n" +
+ " <d:PropertyString>String 1</d:PropertyString>\n" +
+ " </d:PropertyComp>\n" +
+ " </d:PropertyComp>\n" +
+ " </m:properties>\n" +
+ " </a:content>\n" +
+ " </a:entry>\n" +
+ " <a:entry>\n" +
+ " <a:id>ESCompComp(2)</a:id>\n" +
+ " <a:title />\n" +
+ " <a:summary />\n" +
+ " <a:updated>" + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
+ .format(new Date(currentTimeMillis)) + "</a:updated>" +
+ " <a:author>\n" +
+ " <a:name />\n" +
+ " </a:author>\n" +
+ " <a:link rel=\"edit\" href=\"ESCompComp(2)\"/>\n" +
+ " <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\"\n" +
+ " term=\"#olingo.odata.test1.ETCompComp\" />\n" +
+ " <a:content type=\"application/xml\">\n" +
+ " <m:properties>\n" +
+ " <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompComp\">\n" +
+ " <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" +
+ " <d:PropertyInt16 m:type=\"Int16\">987</d:PropertyInt16>\n"
<TRUNCATED>
[13/18] olingo-odata4 git commit: [OLINGO-741] Add pre-validation for
properties in UriParseTreeVisitor
Posted by ch...@apache.org.
[OLINGO-741] Add pre-validation for properties in UriParseTreeVisitor
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/ac6e9e72
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/ac6e9e72
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/ac6e9e72
Branch: refs/heads/OLINGO-640
Commit: ac6e9e725de08d8b74e1e878239f80b64789d85a
Parents: 305f54d
Author: Michael Bolz <mi...@sap.com>
Authored: Thu Jul 30 21:33:49 2015 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Thu Jul 30 21:34:35 2015 +0200
----------------------------------------------------------------------
.../core/uri/parser/UriParseTreeVisitor.java | 29 ++++++----
.../core/uri/antlr/TestFullResourcePath.java | 56 +++++++++++++++++---
2 files changed, 68 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ac6e9e72/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
index 16aa42e..dcccf7c 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
@@ -288,8 +288,21 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
String odi = ctx.vODI.getText();
- if (checkFirst && ctx.vNS == null) {
+ boolean searchInContainer = true;
+ // validate if context type and according property is available
+ // otherwise search in container for first element
+ if (checkFirst && ctx.vNS == null && !context.contextTypes.empty()) {
+ TypeInformation source = context.contextTypes.peek();
+ if (source.type instanceof EdmStructuredType) {
+ EdmStructuredType str = (EdmStructuredType) source.type;
+ EdmElement property = str.getProperty(odi);
+ if (property != null) {
+ searchInContainer = false;
+ }
+ }
+ }
+ if(searchInContainer) {
// check EntitySet
EdmEntitySet edmEntitySet = edmEntityContainer.getEntitySet(odi);
if (edmEntitySet != null) {
@@ -362,8 +375,8 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
}
}
- TypeInformation source = null;
- UriResource lastResourcePart = context.contextUriInfo.getLastResourcePart();
+ final TypeInformation source;
+ final UriResource lastResourcePart = context.contextUriInfo.getLastResourcePart();
if (lastResourcePart == null) {
if (context.contextTypes.empty()) {
@@ -427,7 +440,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
}
if (property instanceof EdmProperty) {
- if (((EdmProperty) property).isPrimitive() == true) {
+ if (((EdmProperty) property).isPrimitive()) {
// create simple property
UriResourcePrimitivePropertyImpl simpleResource = new UriResourcePrimitivePropertyImpl()
.setProperty((EdmProperty) property);
@@ -485,7 +498,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
if (lastResourcePart instanceof UriResourceWithKeysImpl) {
UriResourceWithKeysImpl lastPartWithKeys = (UriResourceWithKeysImpl) lastResourcePart;
- if (lastPartWithKeys.isCollection() == false) {
+ if (!lastPartWithKeys.isCollection()) {
if (lastPartWithKeys.getTypeFilterOnEntry() != null) {
throw wrap(new UriParserSemanticException("Entry typefilters are not chainable, used '"
+ getName(filterEntityType) + "' behind '"
@@ -559,7 +572,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
// e.g. in case of function returning complex data or a list of complex data
UriResourceWithKeysImpl lastPartWithKeys = (UriResourceWithKeysImpl) lastResourcePart;
- if (lastPartWithKeys.isCollection() == false) {
+ if (!lastPartWithKeys.isCollection()) {
if (lastPartWithKeys.getTypeFilterOnEntry() != null) {
throw wrap(new UriParserSemanticException("Entry typefilters are not chainable, used '"
+ getName(filterComplexType) + "' behind '"
@@ -1193,9 +1206,6 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
public Object visitExpandPath(final ExpandPathContext ctx) {
ExpandItemImpl expandItem = new ExpandItemImpl();
- // UriResourceItImpl pathInfoIT = new UriResourceItImpl();
- context.contextUriInfo.getLastResourcePart();
-
// save context
ExpandItemImpl contextExpandItemPathBU = context.contextExpandItemPath;
UriInfoImpl uriInfoResourceBU = context.contextUriInfo;
@@ -1203,7 +1213,6 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
// set tmp context
context.contextExpandItemPath = expandItem;
context.contextUriInfo = new UriInfoImpl().setKind(UriInfoKind.resource);
- // contextUriInfo.addPathInfo(pathInfoIT);
super.visitExpandPath(ctx);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/ac6e9e72/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
index d1ffaab..10240ab 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
@@ -22,6 +22,11 @@ import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edm.EdmEntityContainer;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.http.HttpContentType;
import org.apache.olingo.commons.core.Encoder;
import org.apache.olingo.commons.core.edm.EdmProviderImpl;
@@ -46,6 +51,7 @@ import org.apache.olingo.server.tecsvc.provider.EnumTypeProvider;
import org.apache.olingo.server.tecsvc.provider.PropertyProvider;
import org.junit.Ignore;
import org.junit.Test;
+import org.mockito.Mockito;
public class TestFullResourcePath {
Edm edm = null;
@@ -248,8 +254,8 @@ public class TestFullResourcePath {
.isFunction("BFCESBaseTwoKeyNavRTESBaseTwoKey");
testUri.run("ESTwoKeyNav/olingo.odata.test1.ETBaseTwoKeyNav"
- + "/olingo.odata.test1.BFCESBaseTwoKeyNavRTESBaseTwoKey()"
- + "/olingo.odata.test1.ETTwoBaseTwoKeyNav")
+ + "/olingo.odata.test1.BFCESBaseTwoKeyNavRTESBaseTwoKey()"
+ + "/olingo.odata.test1.ETTwoBaseTwoKeyNav")
.isKind(UriInfoKind.resource).goPath()
.first()
.isEntitySet("ESTwoKeyNav")
@@ -1474,7 +1480,7 @@ public class TestFullResourcePath {
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true);
testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/olingo.odata.test1.ETBaseTwoKeyNav"
- + "/NavPropertyETKeyNavMany(3)")
+ + "/NavPropertyETKeyNavMany(3)")
.isKind(UriInfoKind.resource).goPath()
.first()
.isEntitySet("ESTwoKeyNav")
@@ -1766,7 +1772,7 @@ public class TestFullResourcePath {
.isTypeFilterOnEntry(EntityTypeProvider.nameETBaseTwoKeyNav);
testUri.run("FICRTETTwoKeyNavParam(ParameterInt16=1)(PropertyInt16=2,PropertyString='3')"
- + "/olingo.odata.test1.ETBaseTwoKeyNav")
+ + "/olingo.odata.test1.ETBaseTwoKeyNav")
.isKind(UriInfoKind.resource).goPath()
.first()
.isFunctionImport("FICRTETTwoKeyNavParam")
@@ -2072,6 +2078,45 @@ public class TestFullResourcePath {
.isCount();
}
+ /**
+ * Test for EntitySet and NavigationProperty with same name defined in metadata.
+ * (related to Olingo issue OLINGO-741)
+ */
+ @Test
+ public void yetAnotherSmallTest() throws Exception {
+ TestUriValidator testUri = new TestUriValidator();
+
+ Edm mockEdm = Mockito.mock(Edm.class);
+ EdmEntitySet esCategory = Mockito.mock(EdmEntitySet.class);
+ EdmEntitySet esProduct = Mockito.mock(EdmEntitySet.class);
+ EdmEntityType typeCategory = Mockito.mock(EdmEntityType.class);
+ EdmEntityContainer container = Mockito.mock(EdmEntityContainer.class);
+ EdmNavigationProperty productsNavigation = Mockito.mock(EdmNavigationProperty.class);
+ EdmEntityType productsType = Mockito.mock(EdmEntityType.class);
+
+ Mockito.when(mockEdm.getEntityContainer(null)).thenReturn(container);
+ Mockito.when(typeCategory.getName()).thenReturn("Category");
+ Mockito.when(typeCategory.getNamespace()).thenReturn("NS");
+ Mockito.when(esCategory.getEntityType()).thenReturn(typeCategory);
+ Mockito.when(productsNavigation.getName()).thenReturn("Products");
+ Mockito.when(typeCategory.getProperty("Products")).thenReturn(productsNavigation);
+ Mockito.when(container.getEntitySet("Category")).thenReturn(esCategory);
+ Mockito.when(container.getEntitySet("Products")).thenReturn(esProduct);
+ Mockito.when(productsType.getName()).thenReturn("Products");
+ Mockito.when(productsType.getNamespace()).thenReturn("NS");
+ Mockito.when(productsNavigation.getType()).thenReturn(productsType);
+
+ // test and verify
+ testUri.setEdm(mockEdm)
+ .run("Category", "$expand=Products")
+ .isKind(UriInfoKind.resource).goPath().goExpand()
+ .first()
+ .goPath().first()
+ .isNavProperty("Products", new FullQualifiedName("NS", "Products"), false)
+ .isType(new FullQualifiedName("NS", "Products"), false);
+ Mockito.verifyZeroInteractions(esProduct);
+ }
+
@Test
public void runExpand() throws Exception {
@@ -2362,9 +2407,6 @@ public class TestFullResourcePath {
.goExpand().first()
.isExpandStartType(EntityTypeProvider.nameETBaseTwoKeyNav)
.goPath().first()
- // .isType(EntityTypeProvider.nameETTwoKeyNav)
- // .isTypeFilterOnCollection(EntityTypeProvider.nameETBaseTwoKeyNav)
- // .n()
.isNavProperty("NavPropertyETKeyNavMany", EntityTypeProvider.nameETKeyNav, true);
testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='Hugo')",
[14/18] olingo-odata4 git commit: [OLINGO-743] Add odatapath to
ContextURL
Posted by ch...@apache.org.
[OLINGO-743] Add odatapath to ContextURL
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/5e481b23
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/5e481b23
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/5e481b23
Branch: refs/heads/OLINGO-640
Commit: 5e481b23ec0bf41fa83160eca4ce370e936fd7c7
Parents: ac6e9e7
Author: Michael Bolz <mi...@sap.com>
Authored: Fri Jul 31 15:51:34 2015 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Fri Jul 31 15:51:34 2015 +0200
----------------------------------------------------------------------
.../fit/tecsvc/client/NavigationITCase.java | 37 ++++
.../apache/olingo/fit/util/StringHelper.java | 214 +++++++++++++++++++
.../olingo/commons/api/data/ContextURL.java | 15 +-
.../serializer/utils/ContextURLBuilder.java | 9 +
.../processor/TechnicalEntityProcessor.java | 99 +++++----
.../serializer/utils/ContextURLHelperTest.java | 70 ++++++
6 files changed, 401 insertions(+), 43 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5e481b23/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/NavigationITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/NavigationITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/NavigationITCase.java
index e8147a4..40c1de4 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/NavigationITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/NavigationITCase.java
@@ -20,6 +20,7 @@ package org.apache.olingo.fit.tecsvc.client;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
@@ -31,13 +32,49 @@ import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.fit.AbstractBaseTestITCase;
import org.apache.olingo.fit.tecsvc.TecSvcConst;
+import org.apache.olingo.fit.util.StringHelper;
import org.junit.Test;
+import java.io.InputStream;
+
public final class NavigationITCase extends AbstractBaseTestITCase {
private final ODataClient client = getClient();
@Test
+ public void navigationToEntityWithRelativeContextUrl() throws Exception {
+ // zero navigation
+ final InputStream zeroLevelResponse = client.getRetrieveRequestFactory().getEntityRequest(
+ client.newURIBuilder(TecSvcConst.BASE_URI)
+ .appendEntitySetSegment("ESAllPrim").
+ appendKeySegment(32767).build()).rawExecute();
+
+ String zeroLevelResponseBody = StringHelper.asString(zeroLevelResponse);
+ assertTrue(zeroLevelResponseBody.contains("\"@odata.context\":\"$metadata#ESAllPrim/$entity\""));
+
+ // one navigation
+ final InputStream oneLevelResponse = client.getRetrieveRequestFactory().getEntityRequest(
+ client.newURIBuilder(TecSvcConst.BASE_URI)
+ .appendEntitySetSegment("ESAllPrim").appendKeySegment(32767)
+ .appendNavigationSegment("NavPropertyETTwoPrimOne").build())
+ .rawExecute();
+
+ String oneLevelResponseBody = StringHelper.asString(oneLevelResponse);
+ assertTrue(oneLevelResponseBody.contains("\"@odata.context\":\"../$metadata#ESTwoPrim/$entity\""));
+
+ // two navigation
+ final InputStream twoLevelResponse = client.getRetrieveRequestFactory().getEntityRequest(
+ client.newURIBuilder(TecSvcConst.BASE_URI)
+ .appendEntitySetSegment("ESTwoPrim").appendKeySegment(32767)
+ .appendNavigationSegment("NavPropertyETAllPrimOne")
+ .appendNavigationSegment("NavPropertyETTwoPrimMany").appendKeySegment(-365).build())
+ .rawExecute();
+
+ String twoLevelResponseBody = StringHelper.asString(twoLevelResponse);
+ assertTrue(twoLevelResponseBody.contains("\"@odata.context\":\"../../$metadata#ESTwoPrim/$entity\""));
+ }
+
+ @Test
public void oneLevelToEntity() throws Exception {
final ODataRetrieveResponse<ClientEntity> response =
client.getRetrieveRequestFactory().getEntityRequest(
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5e481b23/fit/src/test/java/org/apache/olingo/fit/util/StringHelper.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/util/StringHelper.java b/fit/src/test/java/org/apache/olingo/fit/util/StringHelper.java
new file mode 100644
index 0000000..8b2e9a1
--- /dev/null
+++ b/fit/src/test/java/org/apache/olingo/fit/util/StringHelper.java
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ * 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.util;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.util.Random;
+
+/**
+ *
+ */
+public class StringHelper {
+
+ public static final String DEFAULT_ENCODING = "UTF-8";
+
+ public static class Stream {
+ private final byte[] data;
+
+ private Stream(final byte[] data) {
+ this.data = data;
+ }
+
+ public Stream(final String content, final String charset) throws UnsupportedEncodingException {
+ this(content.getBytes(charset));
+ }
+
+ public InputStream asStream() {
+ return new ByteArrayInputStream(data);
+ }
+
+ public byte[] asArray() {
+ return data;
+ }
+
+ public int byteLength() {
+ if(data == null) {
+ return -1;
+ }
+ return data.length;
+ }
+
+ public String asString() {
+ return asString(DEFAULT_ENCODING);
+ }
+
+ public String asString(final String charsetName) {
+ return new String(data, Charset.forName(charsetName));
+ }
+
+ public Stream print(final OutputStream out) throws IOException {
+ out.write(data);
+ return this;
+ }
+
+ public Stream print() throws IOException {
+ return print(System.out);
+ }
+
+ public String asStringWithLineSeparation(String separator) throws IOException {
+ BufferedReader br = new BufferedReader(new StringReader(asString()));
+ StringBuilder sb = new StringBuilder(br.readLine());
+ String line = br.readLine();
+ while (line != null) {
+ sb.append(separator).append(line);
+ line = br.readLine();
+ }
+ return sb.toString();
+ }
+
+ public InputStream asStreamWithLineSeparation(String separator) throws IOException {
+ String asString = asStringWithLineSeparation(separator);
+ return new ByteArrayInputStream(asString.getBytes(DEFAULT_ENCODING));
+ }
+
+ /**
+ * Number of lines separated by line breaks (<code>CRLF</code>).
+ * A content string like <code>text\r\nmoreText</code> will result in
+ * a line count of <code>2</code>.
+ *
+ * @return lines count
+ */
+ public int linesCount() {
+ return StringHelper.countLines(asString(), "\r\n");
+ }
+ }
+
+ public static Stream toStream(final InputStream stream) throws IOException {
+ byte[] result = new byte[0];
+ byte[] tmp = new byte[8192];
+ int readCount = stream.read(tmp);
+ while (readCount >= 0) {
+ byte[] innerTmp = new byte[result.length + readCount];
+ System.arraycopy(result, 0, innerTmp, 0, result.length);
+ System.arraycopy(tmp, 0, innerTmp, result.length, readCount);
+ result = innerTmp;
+ readCount = stream.read(tmp);
+ }
+ stream.close();
+ return new Stream(result);
+ }
+
+ public static Stream toStream(final String content) {
+ return toStream(content, DEFAULT_ENCODING);
+ }
+
+ public static Stream toStream(final String content, final String charset) {
+ try {
+ return new Stream(content, charset);
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 should be supported on each system.");
+ }
+ }
+
+ /**
+ * Read the input stream into an string with default encoding (see StringHelper.DEFAULT_ENCODING).
+ *
+ * @param in stream which is read
+ * @return content of stream as string
+ * @throws IOException
+ */
+ public static String asString(final InputStream in) throws IOException {
+ return toStream(in).asString();
+ }
+
+ public static int countLines(final String content, final String lineBreak) {
+ if (content == null) {
+ return -1;
+ }
+
+ int lastPos = content.indexOf(lineBreak);
+ int count = 1;
+
+ while (lastPos >= 0) {
+ lastPos = content.indexOf(lineBreak, lastPos + 1);
+ count++;
+ }
+ return count;
+ }
+
+ /**
+ * Encapsulate given content in an {@link InputStream} with charset <code>UTF-8</code>.
+ *
+ * @param content to encapsulate content
+ * @return content as stream
+ */
+ public static InputStream encapsulate(final String content) {
+ try {
+ return encapsulate(content, DEFAULT_ENCODING);
+ } catch (UnsupportedEncodingException e) {
+ // we know that UTF-8 is supported
+ throw new RuntimeException("UTF-8 MUST be supported.", e);
+ }
+ }
+
+ /**
+ * Encapsulate given content in an {@link InputStream} with given charset.
+ *
+ * @param content to encapsulate content
+ * @param charset to be used charset
+ * @return content as stream
+ * @throws UnsupportedEncodingException if charset is not supported
+ */
+ public static InputStream encapsulate(final String content, final String charset)
+ throws UnsupportedEncodingException {
+ return new ByteArrayInputStream(content.getBytes(charset));
+ }
+
+ /**
+ * Generate a string with given length containing random upper case characters ([A-Z]).
+ *
+ * @param len length of to generated string
+ * @return random upper case characters ([A-Z]).
+ */
+ public static InputStream generateDataStream(final int len) {
+ return encapsulate(generateData(len));
+ }
+
+ /**
+ * Generates a string with given length containing random upper case characters ([A-Z]).
+ * @param len length of the generated string
+ * @return random upper case characters ([A-Z])
+ */
+ public static String generateData(final int len) {
+ Random random = new Random();
+ StringBuilder b = new StringBuilder(len);
+ for (int j = 0; j < len; j++) {
+ final char c = (char) ('A' + random.nextInt('Z' - 'A' + 1));
+ b.append(c);
+ }
+ return b.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5e481b23/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java
index 3c482c7..bf31d71 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ContextURL.java
@@ -48,6 +48,12 @@ public class ContextURL {
private Suffix suffix;
+ private String odataPath;
+
+ public String getODataPath() {
+ return odataPath;
+ }
+
public enum Suffix {
ENTITY("$entity"), REFERENCE("$ref"),
@@ -55,7 +61,7 @@ public class ContextURL {
private final String representation;
- private Suffix(final String representation) {
+ Suffix(final String representation) {
this.representation = representation;
}
@@ -128,7 +134,12 @@ public class ContextURL {
public static final class Builder {
- private ContextURL contextURL = new ContextURL();
+ private final ContextURL contextURL = new ContextURL();
+
+ public Builder oDataPath(String oDataPath) {
+ contextURL.odataPath = oDataPath;
+ return this;
+ }
public Builder serviceRoot(final URI serviceRoot) {
contextURL.serviceRoot = serviceRoot;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5e481b23/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilder.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilder.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilder.java
index e79a295..3cc7744 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilder.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilder.java
@@ -35,7 +35,16 @@ public final class ContextURLBuilder {
StringBuilder result = new StringBuilder();
if (contextURL.getServiceRoot() != null) {
result.append(contextURL.getServiceRoot());
+ } else if(contextURL.getODataPath() != null) {
+ String oDataPath = contextURL.getODataPath();
+ char[] chars = oDataPath.toCharArray();
+ for (int i = 1; i < chars.length-1; i++) {
+ if(chars[i] == '/' && chars[i-1] != '/') {
+ result.append("../");
+ }
+ }
}
+
result.append(Constants.METADATA);
if (contextURL.getEntitySetOrSingletonOrType() != null) {
result.append('#');
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5e481b23/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
index cba853d..a47f367 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
@@ -187,7 +187,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
+ odata.createUriHelper().buildCanonicalURL(edmEntitySet, entity);
final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
if (returnPreference == null || returnPreference == Return.REPRESENTATION) {
- response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, responseFormat, expand, null)
+ response.setContent(serializeEntity(request, entity, edmEntitySet, edmEntityType, responseFormat, expand, null)
.getContent());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
response.setStatusCode(HttpStatusCode.CREATED.getStatusCode());
@@ -243,7 +243,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
if (returnPreference == null || returnPreference == Return.REPRESENTATION) {
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
- response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, responseFormat, null, null)
+ response.setContent(serializeEntity(request, entity, edmEntitySet, edmEntityType, responseFormat)
.getContent());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
} else {
@@ -271,12 +271,12 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
request.getHeaders(HttpHeader.IF_NONE_MATCH));
checkRequestFormat(requestFormat);
dataProvider.setMedia(entity, odata.createFixedFormatDeserializer().binary(request.getBody()),
- requestFormat.toContentTypeString());
+ requestFormat.toContentTypeString());
final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
if (returnPreference == null || returnPreference == Return.REPRESENTATION) {
- response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, responseFormat, null, null)
- .getContent());
+ response.setContent(serializeEntity(request, entity, edmEntitySet, edmEntityType, responseFormat)
+ .getContent());
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
} else {
@@ -385,16 +385,17 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
final Entity entity = readEntity(uriInfo, true);
dataProvider.deleteReference(entity,
- lastNavigation.getProperty(),
- (uriInfo.getIdOption() != null) ? uriInfo.getIdOption().getValue() : null,
- request.getRawBaseUri());
+ lastNavigation.getProperty(),
+ (uriInfo.getIdOption() != null) ? uriInfo.getIdOption().getValue() : null,
+ request.getRawBaseUri());
response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
}
@Override
- public void readReferenceCollection(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
- final ContentType requestedContentType) throws ODataApplicationException, ODataLibraryException {
+ public void readReferenceCollection(final ODataRequest request, final ODataResponse response,
+ final UriInfo uriInfo, final ContentType requestedContentType)
+ throws ODataApplicationException, ODataLibraryException {
readEntityCollection(request, response, uriInfo, requestedContentType, true);
}
@@ -440,7 +441,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
final SerializerResult serializerResult = isReference ?
serializeReference(entity, edmEntitySet, requestedFormat) :
- serializeEntity(entitySerialization, edmEntitySet, edmEntityType, requestedFormat, expand, select);
+ serializeEntity(request, entitySerialization, edmEntitySet, edmEntityType, requestedFormat, expand, select);
if (entity.getETag() != null) {
response.setHeader(HttpHeader.ETAG, entity.getETag());
@@ -516,7 +517,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
// Serialize
final SerializerResult serializerResult = (isReference) ?
serializeReferenceCollection(entitySetSerialization, edmEntitySet, requestedContentType, countOption) :
- serializeEntityCollection(entitySetSerialization, edmEntitySet, edmEntityType, requestedContentType,
+ serializeEntityCollection(request, entitySetSerialization, edmEntitySet, edmEntityType, requestedContentType,
expand, select, countOption);
response.setContent(serializerResult.getContent());
@@ -528,21 +529,23 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
}
}
- private SerializerResult serializeEntityCollection(final EntityCollection entityCollection,
+ private SerializerResult serializeEntityCollection(final ODataRequest request, final EntityCollection
+ entityCollection,
final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType, final ContentType requestedFormat,
final ExpandOption expand, final SelectOption select, final CountOption countOption)
throws ODataLibraryException {
-
+
return odata.createSerializer(requestedFormat).entityCollection(
- serviceMetadata,
- edmEntityType,
- entityCollection,
- EntityCollectionSerializerOptions.with()
- .contextURL(isODataMetadataNone(requestedFormat) ? null :
- getContextUrl(edmEntitySet, edmEntityType, false, expand, select))
- .count(countOption)
- .expand(expand).select(select)
- .build());
+ serviceMetadata,
+ edmEntityType,
+ entityCollection,
+ EntityCollectionSerializerOptions.with()
+ .contextURL(isODataMetadataNone(requestedFormat) ? null :
+ getContextUrl(request.getRawODataPath(), edmEntitySet, edmEntityType, false, expand,
+ select))
+ .count(countOption)
+ .expand(expand).select(select)
+ .build());
}
private SerializerResult serializeReferenceCollection(final EntityCollection entityCollection,
@@ -550,36 +553,50 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
throws ODataLibraryException {
return odata.createSerializer(requestedFormat)
- .referenceCollection(serviceMetadata, edmEntitySet, entityCollection,ReferenceCollectionSerializerOptions.with()
- .contextURL(ContextURL.with().asCollection().suffix(Suffix.REFERENCE).build())
- .count(countOption).build());
+ .referenceCollection(serviceMetadata, edmEntitySet, entityCollection,
+ ReferenceCollectionSerializerOptions.with()
+ .contextURL(ContextURL.with().asCollection().suffix(Suffix.REFERENCE).build())
+ .count(countOption).build());
}
private SerializerResult serializeReference(final Entity entity, final EdmEntitySet edmEntitySet,
final ContentType requestedFormat) throws ODataLibraryException {
return odata.createSerializer(requestedFormat)
.reference(serviceMetadata, edmEntitySet, entity, ReferenceSerializerOptions.with()
- .contextURL(ContextURL.with().suffix(Suffix.REFERENCE).build()).build());
+ .contextURL(ContextURL.with().suffix(Suffix.REFERENCE).build()).build());
}
- private SerializerResult serializeEntity(final Entity entity,
- final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType, final ContentType requestedFormat,
- final ExpandOption expand, final SelectOption select) throws ODataLibraryException {
+ private SerializerResult serializeEntity(final ODataRequest request, final Entity entity,
+ final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType,
+ final ContentType requestedFormat) throws ODataLibraryException {
+ return serializeEntity(request, entity, edmEntitySet, edmEntityType, requestedFormat, null, null);
+ }
+
+ private SerializerResult serializeEntity(final ODataRequest request, final Entity entity,
+ final EdmEntitySet edmEntitySet, final EdmEntityType edmEntityType,
+ final ContentType requestedFormat,
+ final ExpandOption expand, final SelectOption select)
+ throws ODataLibraryException {
+
+ ContextURL contextUrl = isODataMetadataNone(requestedFormat) ? null :
+ getContextUrl(request.getRawODataPath(), edmEntitySet, edmEntityType, true, expand, null);
return odata.createSerializer(requestedFormat).entity(
- serviceMetadata,
- edmEntityType,
- entity,
- EntitySerializerOptions.with()
- .contextURL(isODataMetadataNone(requestedFormat) ? null :
- getContextUrl(edmEntitySet, edmEntityType, true, expand, select))
- .expand(expand).select(select)
- .build());
+ serviceMetadata,
+ edmEntityType,
+ entity,
+ EntitySerializerOptions.with()
+ .contextURL(contextUrl)
+ .expand(expand).select(select)
+ .build());
}
- private ContextURL getContextUrl(final EdmEntitySet entitySet, final EdmEntityType entityType,
- final boolean isSingleEntity, final ExpandOption expand, final SelectOption select) throws ODataLibraryException {
- Builder builder = ContextURL.with();
+ private ContextURL getContextUrl(String rawODataPath, final EdmEntitySet entitySet, final EdmEntityType entityType,
+ final boolean isSingleEntity, final ExpandOption expand, final SelectOption select)
+ throws ODataLibraryException {
+ //
+ //
+ Builder builder = ContextURL.with().oDataPath(rawODataPath);
builder = entitySet == null ?
isSingleEntity ? builder.type(entityType) : builder.asCollection().type(entityType) :
builder.entitySet(entitySet);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/5e481b23/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java
index b94f97e..fe86896 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java
@@ -95,6 +95,76 @@ public class ContextURLHelperTest {
ContextURLBuilder.create(contextURL).toASCIIString());
}
+
+ @Test
+ public void buildEntity() throws Exception {
+ final EdmEntitySet entitySet = entityContainer.getEntitySet("ESTwoPrim");
+ final ContextURL contextURL = ContextURL.with().entitySet(entitySet).suffix(ContextURL.Suffix.ENTITY).build();
+ assertEquals("$metadata#ESTwoPrim/$entity", ContextURLBuilder.create(contextURL).toASCIIString());
+ }
+
+ // /odata.svc/ESAllPrim(32767)/NavPropertyETTwoPrimOne/NavPropertyETAllPrimOne/
+ // NavPropertyETTwoPrimOne/NavPropertyETAllPrimOne/NavPropertyETTwoPrimOne
+ // @odata.context: "../../../../../$metadata#ESTwoPrim/$entity"
+ @Test
+ public void buildRelativeFiveNavigation() throws Exception {
+ final EdmEntitySet entitySet = entityContainer.getEntitySet("ESTwoPrim");
+ String odataPath = "ESAllPrim(32767)/NavPropertyETTwoPrimOne/NavPropertyETAllPrimOne/" +
+ "NavPropertyETTwoPrimOne/NavPropertyETAllPrimOne/NavPropertyETTwoPrimOne";
+ ContextURL contextURL = ContextURL.with()
+ .oDataPath("/" + odataPath)
+ .entitySet(entitySet).suffix(ContextURL.Suffix.ENTITY).build();
+ assertEquals("../../../../../$metadata#ESTwoPrim/$entity", ContextURLBuilder.create(contextURL).toASCIIString());
+
+ // removed leading '/'
+ contextURL = ContextURL.with()
+ .oDataPath(odataPath)
+ .entitySet(entitySet).suffix(ContextURL.Suffix.ENTITY).build();
+ assertEquals("../../../../../$metadata#ESTwoPrim/$entity", ContextURLBuilder.create(contextURL).toASCIIString());
+ }
+
+ // odata.svc/ESAllPrim(32767)/NavPropertyETTwoPrimOne
+ // @odata.context: "$metadata#ESTwoPrim/$entity",
+ @Test
+ public void buildRelativeNavigation() throws Exception {
+ final EdmEntitySet entitySet = entityContainer.getEntitySet("ESTwoPrim");
+ final String oDataPath = "ESAllPrim(32767)/NavPropertyETTwoPrimOne";
+ ContextURL contextURL = ContextURL.with().oDataPath("/" + oDataPath)
+ .entitySet(entitySet).suffix(ContextURL.Suffix.ENTITY).build();
+ assertEquals("../$metadata#ESTwoPrim/$entity", ContextURLBuilder.create(contextURL).toASCIIString());
+
+ // without leading '/'
+ contextURL = ContextURL.with().oDataPath(oDataPath)
+ .entitySet(entitySet).suffix(ContextURL.Suffix.ENTITY).build();
+ assertEquals("../$metadata#ESTwoPrim/$entity", ContextURLBuilder.create(contextURL).toASCIIString());
+ }
+
+ // /odata.svc/ESAllPrim(32767)/NavPropertyETTwoPrimOne/NavPropertyETAllPrimOne
+ // @odata.context: "$metadata#ESAllPrim/$entity",
+ @Test
+ public void buildRelativeTwoNavigation() throws Exception {
+ final EdmEntitySet entitySet = entityContainer.getEntitySet("ESAllPrim");
+ String oDataPath = "ESAllPrim(32767)/NavPropertyETTwoPrimOne/NavPropertyETAllPrimOne";
+ ContextURL contextURL = ContextURL.with()
+ .oDataPath("/" + oDataPath)
+ .entitySet(entitySet).suffix(ContextURL.Suffix.ENTITY).build();
+ assertEquals("../../$metadata#ESAllPrim/$entity", ContextURLBuilder.create(contextURL).toASCIIString());
+
+ // without leading '/'
+ contextURL = ContextURL.with().oDataPath(oDataPath)
+ .entitySet(entitySet).suffix(ContextURL.Suffix.ENTITY).build();
+ assertEquals("../../$metadata#ESAllPrim/$entity", ContextURLBuilder.create(contextURL).toASCIIString());
+
+ // without unnecessary '///'
+ contextURL = ContextURL.with().oDataPath("///" + oDataPath)
+ .entitySet(entitySet).suffix(ContextURL.Suffix.ENTITY).build();
+ assertEquals("../../$metadata#ESAllPrim/$entity", ContextURLBuilder.create(contextURL).toASCIIString());
+ // without unnecessary '///' between
+ contextURL = ContextURL.with().oDataPath(oDataPath.replace("/", "///"))
+ .entitySet(entitySet).suffix(ContextURL.Suffix.ENTITY).build();
+ assertEquals("../../$metadata#ESAllPrim/$entity", ContextURLBuilder.create(contextURL).toASCIIString());
+ }
+
@Test
public void buildExpandAll() throws Exception {
final EdmEntitySet entitySet = entityContainer.getEntitySet("ESTwoPrim");
[09/18] olingo-odata4 git commit: [OLINGO-713] Added tutorial project
for system query options - expand/select
Posted by ch...@apache.org.
[OLINGO-713] Added tutorial project for system query options - expand/select
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/b477bde0
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/b477bde0
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/b477bde0
Branch: refs/heads/OLINGO-640
Commit: b477bde07b190717b0e6ef443efcef1ca1b3d57e
Parents: 3dae763
Author: Michael Bolz <mi...@sap.com>
Authored: Mon Jul 27 09:57:17 2015 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Mon Jul 27 10:12:14 2015 +0200
----------------------------------------------------------------------
samples/tutorials/p5_queryoptions-tis/pom.xml | 79 ++++++
.../myservice/mynamespace/data/Storage.java | 130 ++++++++++
.../mynamespace/service/DemoEdmProvider.java | 154 ++++++++++++
.../service/DemoEntityCollectionProcessor.java | 142 +++++++++++
.../service/DemoEntityProcessor.java | 118 +++++++++
.../service/DemoPrimitiveProcessor.java | 150 +++++++++++
.../java/myservice/mynamespace/util/Util.java | 105 ++++++++
.../myservice/mynamespace/web/DemoServlet.java | 76 ++++++
.../src/main/webapp/WEB-INF/web.xml | 40 +++
.../src/main/webapp/index.jsp | 26 ++
samples/tutorials/p5_queryoptions/pom.xml | 79 ------
.../myservice/mynamespace/data/Storage.java | 130 ----------
.../mynamespace/service/DemoEdmProvider.java | 154 ------------
.../service/DemoEntityCollectionProcessor.java | 142 -----------
.../service/DemoEntityProcessor.java | 118 ---------
.../service/DemoPrimitiveProcessor.java | 150 -----------
.../java/myservice/mynamespace/util/Util.java | 105 --------
.../myservice/mynamespace/web/DemoServlet.java | 76 ------
.../src/main/webapp/WEB-INF/web.xml | 40 ---
.../p5_queryoptions/src/main/webapp/index.jsp | 26 --
samples/tutorials/p6_queryoptions-es/pom.xml | 80 ++++++
.../myservice/mynamespace/data/Storage.java | 252 +++++++++++++++++++
.../mynamespace/service/DemoEdmProvider.java | 211 ++++++++++++++++
.../service/DemoEntityCollectionProcessor.java | 160 ++++++++++++
.../service/DemoEntityProcessor.java | 235 +++++++++++++++++
.../service/DemoPrimitiveProcessor.java | 150 +++++++++++
.../java/myservice/mynamespace/util/Util.java | 149 +++++++++++
.../myservice/mynamespace/web/DemoServlet.java | 75 ++++++
.../src/main/webapp/WEB-INF/web.xml | 34 +++
.../src/main/webapp/index.jsp | 43 ++++
samples/tutorials/pom.xml | 3 +-
31 files changed, 2411 insertions(+), 1021 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions-tis/pom.xml
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions-tis/pom.xml b/samples/tutorials/p5_queryoptions-tis/pom.xml
new file mode 100755
index 0000000..db1e18c
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions-tis/pom.xml
@@ -0,0 +1,79 @@
+<?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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>my.group.id</groupId>
+ <artifactId>DemoService-QueryOptions-TIS</artifactId>
+ <packaging>war</packaging>
+ <version>0.0.1</version>
+
+ <name>${project.artifactId}-Webapp</name>
+
+ <build>
+ <finalName>DemoService</finalName>
+ </build>
+
+ <properties>
+ <javax.version>2.5</javax.version>
+ <odata.version>4.0.0-beta-03</odata.version>
+ <slf4j.version>1.7.7</slf4j.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>${javax.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>odata-server-api</artifactId>
+ <version>${odata.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>odata-server-core</artifactId>
+ <version>${odata.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>odata-commons-api</artifactId>
+ <version>${odata.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>odata-commons-core</artifactId>
+ <version>${odata.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>${slf4j.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/data/Storage.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/data/Storage.java b/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/data/Storage.java
new file mode 100755
index 0000000..2aa9fac
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/data/Storage.java
@@ -0,0 +1,130 @@
+/*
+ * 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 myservice.mynamespace.data;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import myservice.mynamespace.service.DemoEdmProvider;
+import myservice.mynamespace.util.Util;
+
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntityCollection;
+import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.data.ValueType;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.uri.UriParameter;
+
+public class Storage {
+
+ private List<Entity> productList;
+
+ public Storage() {
+ productList = new ArrayList<Entity>();
+ initSampleData();
+ }
+
+ /* PUBLIC FACADE */
+
+ public EntityCollection readEntitySetData(EdmEntitySet edmEntitySet)throws ODataApplicationException{
+
+ // actually, this is only required if we have more than one Entity Sets
+ if(edmEntitySet.getName().equals(DemoEdmProvider.ES_PRODUCTS_NAME)){
+ return getProducts();
+ }
+
+ return null;
+ }
+
+ public Entity readEntityData(EdmEntitySet edmEntitySet, List<UriParameter> keyParams)
+ throws ODataApplicationException{
+
+ EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+
+ // actually, this is only required if we have more than one Entity Type
+ if(edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)){
+ return getProduct(edmEntityType, keyParams);
+ }
+
+ return null;
+ }
+
+
+
+ /* INTERNAL */
+
+ private EntityCollection getProducts(){
+ EntityCollection retEntitySet = new EntityCollection();
+
+ for(Entity productEntity : this.productList){
+ retEntitySet.getEntities().add(productEntity);
+ }
+
+ return retEntitySet;
+ }
+
+
+ private Entity getProduct(EdmEntityType edmEntityType, List<UriParameter> keyParams)
+ throws ODataApplicationException{
+
+ // the list of entities at runtime
+ EntityCollection entitySet = getProducts();
+
+ /* generic approach to find the requested entity */
+ Entity requestedEntity = Util.findEntity(edmEntityType, entitySet, keyParams);
+
+ if(requestedEntity == null){
+ // this variable is null if our data doesn't contain an entity for the requested key
+ // Throw suitable exception
+ throw new ODataApplicationException("Entity for requested key doesn't exist",
+ HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
+ }
+
+ return requestedEntity;
+ }
+
+ /* HELPER */
+
+ private void initSampleData(){
+
+ // add some sample product entities
+ productList.add(new Entity()
+ .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1))
+ .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Basic 15"))
+ .addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
+ "Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 40GB")));
+
+ productList.add(new Entity()
+ .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2))
+ .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "1UMTS PDA"))
+ .addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
+ "Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network")));
+
+ productList.add(new Entity()
+ .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3))
+ .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Ergo Screen"))
+ .addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
+ "19 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960")));
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java b/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
new file mode 100755
index 0000000..3c28a21
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
@@ -0,0 +1,154 @@
+/*
+ * 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 myservice.mynamespace.service;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.olingo.commons.api.ODataException;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
+import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
+import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo;
+import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet;
+import org.apache.olingo.commons.api.edm.provider.CsdlEntityType;
+import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
+import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef;
+import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
+
+public class DemoEdmProvider extends CsdlAbstractEdmProvider {
+
+ // Service Namespace
+ public static final String NAMESPACE = "OData.Demo";
+
+ // EDM Container
+ public static final String CONTAINER_NAME = "Container";
+ public static final FullQualifiedName CONTAINER = new FullQualifiedName(NAMESPACE, CONTAINER_NAME);
+
+ // Entity Types Names
+ public static final String ET_PRODUCT_NAME = "Product";
+ public static final FullQualifiedName ET_PRODUCT_FQN = new FullQualifiedName(NAMESPACE, ET_PRODUCT_NAME);
+
+ // Entity Set Names
+ public static final String ES_PRODUCTS_NAME = "Products";
+
+ @Override
+ public CsdlEntityType getEntityType(FullQualifiedName entityTypeName)
+ throws ODataException {
+ // this method is called for one of the EntityTypes that are configured in the Schema
+ if (ET_PRODUCT_FQN.equals(entityTypeName)) {
+
+ // create EntityType properties
+ CsdlProperty id = new CsdlProperty().setName("ID").setType(
+ EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
+ CsdlProperty name = new CsdlProperty().setName("Name").setType(
+ EdmPrimitiveTypeKind.String.getFullQualifiedName());
+ CsdlProperty description = new CsdlProperty().setName("Description").setType(
+ EdmPrimitiveTypeKind.String.getFullQualifiedName());
+
+ // create PropertyRef for Key element
+ CsdlPropertyRef propertyRef = new CsdlPropertyRef();
+ propertyRef.setName("ID");
+
+ // configure EntityType
+ CsdlEntityType entityType = new CsdlEntityType();
+ entityType.setName(ET_PRODUCT_NAME);
+ entityType.setProperties(Arrays.asList(id, name, description));
+ entityType.setKey(Collections.singletonList(propertyRef));
+
+ return entityType;
+ }
+
+ return null;
+
+ }
+
+ @Override
+ public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer,
+ String entitySetName) throws ODataException {
+ if (entityContainer.equals(CONTAINER)) {
+ if (entitySetName.equals(ES_PRODUCTS_NAME)) {
+ CsdlEntitySet entitySet = new CsdlEntitySet();
+ entitySet.setName(ES_PRODUCTS_NAME);
+ entitySet.setType(ET_PRODUCT_FQN);
+
+ return entitySet;
+ }
+ }
+
+ return null;
+
+ }
+
+ @Override
+ public CsdlEntityContainerInfo getEntityContainerInfo(
+ FullQualifiedName entityContainerName) throws ODataException {
+ // This method is invoked when displaying the service document at
+ // e.g. http://localhost:8080/DemoService/DemoService.svc
+ if (entityContainerName == null || entityContainerName.equals(CONTAINER)) {
+ CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo();
+ entityContainerInfo.setContainerName(CONTAINER);
+ return entityContainerInfo;
+ }
+
+ return null;
+
+ }
+
+ @Override
+ public List<CsdlSchema> getSchemas() throws ODataException {
+ // create Schema
+ CsdlSchema schema = new CsdlSchema();
+ schema.setNamespace(NAMESPACE);
+
+ // add EntityTypes
+ List<CsdlEntityType> entityTypes = new ArrayList<CsdlEntityType>();
+ entityTypes.add(getEntityType(ET_PRODUCT_FQN));
+ schema.setEntityTypes(entityTypes);
+
+ // add EntityContainer
+ schema.setEntityContainer(getEntityContainer());
+
+ // finally
+ List<CsdlSchema> schemas = new ArrayList<CsdlSchema>();
+ schemas.add(schema);
+
+ return schemas;
+
+ }
+
+ @Override
+ public CsdlEntityContainer getEntityContainer() throws ODataException {
+ // create EntitySets
+ List<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();
+ entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME));
+
+ // create EntityContainer
+ CsdlEntityContainer entityContainer = new CsdlEntityContainer();
+ entityContainer.setName(CONTAINER_NAME);
+ entityContainer.setEntitySets(entitySets);
+
+ return entityContainer;
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java b/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java
new file mode 100755
index 0000000..fc58c23
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.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 myservice.mynamespace.service;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Locale;
+
+import myservice.mynamespace.data.Storage;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntityCollection;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
+import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.serializer.SerializerResult;
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+import org.apache.olingo.server.api.uri.queryoption.CountOption;
+import org.apache.olingo.server.api.uri.queryoption.SkipOption;
+import org.apache.olingo.server.api.uri.queryoption.TopOption;
+
+public class DemoEntityCollectionProcessor implements EntityCollectionProcessor {
+
+ private OData odata;
+ private ServiceMetadata serviceMetadata;
+ private Storage storage;
+
+ public DemoEntityCollectionProcessor(Storage storage) {
+ this.storage = storage;
+ }
+
+ public void init(OData odata, ServiceMetadata serviceMetadata) {
+ this.odata = odata;
+ this.serviceMetadata = serviceMetadata;
+ }
+
+ public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo,
+ ContentType responseFormat) throws ODataApplicationException, SerializerException {
+
+ // 1st retrieve the requested EntitySet from the uriInfo (representation of the parsed URI)
+ List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+ // in our example, the first segment is the EntitySet
+ UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
+ EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
+
+ // 2nd: fetch the data from backend for this requested EntitySetName and deliver as EntitySet
+ EntityCollection entityCollection = storage.readEntitySetData(edmEntitySet);
+
+ // 3rd: apply System Query Options
+ // modify the result set according to the query options, specified by the end user
+ List<Entity> entityList = entityCollection.getEntities();
+ EntityCollection returnEntityCollection = new EntityCollection();
+
+ // handle $count: always return the original number of entities, without considering $top and $skip
+ CountOption countOption = uriInfo.getCountOption();
+ if (countOption != null) {
+ boolean isCount = countOption.getValue();
+ if (isCount) {
+ returnEntityCollection.setCount(entityList.size());
+ }
+ }
+
+ // handle $skip
+ SkipOption skipOption = uriInfo.getSkipOption();
+ if (skipOption != null) {
+ int skipNumber = skipOption.getValue();
+ if (skipNumber >= 0 && skipNumber <= entityList.size()) {
+ entityList = entityList.subList(skipNumber, entityList.size());
+ } else {
+ throw new ODataApplicationException("Invalid value for $skip", HttpStatusCode.BAD_REQUEST.getStatusCode(),
+ Locale.ROOT);
+ }
+ }
+
+ // handle $top
+ TopOption topOption = uriInfo.getTopOption();
+ if (topOption != null) {
+ int topNumber = topOption.getValue();
+ if (topNumber >= 0 && topNumber <= entityList.size()) {
+ entityList = entityList.subList(0, topNumber);
+ } else {
+ throw new ODataApplicationException("Invalid value for $top", HttpStatusCode.BAD_REQUEST.getStatusCode(),
+ Locale.ROOT);
+ }
+ }
+
+ // after applying the system query options, create the EntityCollection based on the reduced list
+ for (Entity entity : entityList) {
+ returnEntityCollection.getEntities().add(entity);
+ }
+
+ // 4th: create a serializer based on the requested format (json)
+ ODataFormat format = ODataFormat.fromContentType(responseFormat);
+ ODataSerializer serializer = odata.createSerializer(format);
+
+ // and serialize the content: transform from the EntitySet object to InputStream
+ EdmEntityType edmEntityType = edmEntitySet.getEntityType();
+ ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build();
+
+ EntityCollectionSerializerOptions opts =
+ EntityCollectionSerializerOptions.with().contextURL(contextUrl).count(countOption).build();
+ SerializerResult serializerResult =
+ serializer.entityCollection(serviceMetadata, edmEntityType, returnEntityCollection, opts);
+ InputStream serializedContent = serializerResult.getContent();
+
+ // 5th: configure the response object: set the body, headers and status code
+ response.setContent(serializedContent);
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java b/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java
new file mode 100755
index 0000000..81453a0
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java
@@ -0,0 +1,118 @@
+/*
+ * 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 myservice.mynamespace.service;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Locale;
+
+import myservice.mynamespace.data.Storage;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.deserializer.DeserializerException;
+import org.apache.olingo.server.api.processor.EntityProcessor;
+import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.serializer.SerializerResult;
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.uri.UriParameter;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+
+public class DemoEntityProcessor implements EntityProcessor {
+
+ private OData odata;
+ private ServiceMetadata serviceMetadata;
+ private Storage storage;
+
+ public DemoEntityProcessor(Storage storage) {
+ this.storage = storage;
+ }
+
+ public void init(OData odata, ServiceMetadata serviceMetadata) {
+ this.odata = odata;
+ this.serviceMetadata = serviceMetadata;
+ }
+
+ public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
+ throws ODataApplicationException, SerializerException {
+
+ // 1. retrieve the Entity Type
+ List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+ // Note: only in our example we can assume that the first segment is the EntitySet
+ UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
+ EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
+
+ // 2. retrieve the data from backend
+ List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
+ Entity entity = storage.readEntityData(edmEntitySet, keyPredicates);
+
+ // 3. serialize
+ EdmEntityType entityType = edmEntitySet.getEntityType();
+
+ ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).suffix(ContextURL.Suffix.ENTITY).build();
+ // expand and select currently not supported
+ EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build();
+
+ ODataFormat oDataFormat = ODataFormat.fromContentType(responseFormat);
+ ODataSerializer serializer = this.odata.createSerializer(oDataFormat);
+ SerializerResult serializerResult = serializer.entity(serviceMetadata, entityType, entity, options);
+ InputStream entityStream = serializerResult.getContent();
+
+ // 4. configure the response object
+ response.setContent(entityStream);
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
+ }
+
+ /*
+ * These processor methods are not handled in this tutorial
+ */
+
+ public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat,
+ ContentType responseFormat)
+ throws ODataApplicationException, DeserializerException, SerializerException {
+ throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+
+ public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat,
+ ContentType responseFormat)
+ throws ODataApplicationException, DeserializerException, SerializerException {
+ throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+
+ public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo)
+ throws ODataApplicationException {
+ throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java b/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java
new file mode 100755
index 0000000..64f7949
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java
@@ -0,0 +1,150 @@
+/*
+ * 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 myservice.mynamespace.service;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Locale;
+
+import myservice.mynamespace.data.Storage;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpHeader;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.deserializer.DeserializerException;
+import org.apache.olingo.server.api.processor.PrimitiveProcessor;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.serializer.SerializerResult;
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.uri.UriParameter;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+import org.apache.olingo.server.api.uri.UriResourceProperty;
+
+public class DemoPrimitiveProcessor implements PrimitiveProcessor {
+
+ private OData odata;
+ private Storage storage;
+
+ public DemoPrimitiveProcessor(Storage storage) {
+ this.storage = storage;
+ }
+
+ public void init(OData odata, ServiceMetadata serviceMetadata) {
+ this.odata = odata;
+
+ }
+
+ /*
+ * In our example, the URL would be: http://localhost:8080/DemoService/DemoService.svc/Products(1)/Name
+ * and the response:
+ * {
+ * @odata.context: "$metadata#Products/Name",
+ * value: "Notebook Basic 15"
+ * }
+ * */
+ public void readPrimitive(ODataRequest request, ODataResponse response,
+ UriInfo uriInfo, ContentType responseFormat)
+ throws ODataApplicationException, SerializerException {
+
+ // 1. Retrieve info from URI
+ // 1.1. retrieve the info about the requested entity set
+ List<UriResource> resourceParts = uriInfo.getUriResourceParts();
+ // Note: only in our example we can rely that the first segment is the EntitySet
+ UriResourceEntitySet uriEntityset = (UriResourceEntitySet) resourceParts.get(0);
+ EdmEntitySet edmEntitySet = uriEntityset.getEntitySet();
+ // the key for the entity
+ List<UriParameter> keyPredicates = uriEntityset.getKeyPredicates();
+
+ // 1.2. retrieve the requested (Edm) property
+ // the last segment is the Property
+ UriResourceProperty uriProperty = (UriResourceProperty)resourceParts.get(resourceParts.size() -1);
+ EdmProperty edmProperty = uriProperty.getProperty();
+ String edmPropertyName = edmProperty.getName();
+ // in our example, we know we have only primitive types in our model
+ EdmPrimitiveType edmPropertyType = (EdmPrimitiveType) edmProperty.getType();
+
+
+ // 2. retrieve data from backend
+ // 2.1. retrieve the entity data, for which the property has to be read
+ Entity entity = storage.readEntityData(edmEntitySet, keyPredicates);
+ if (entity == null) { // Bad request
+ throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
+ }
+
+ // 2.2. retrieve the property data from the entity
+ Property property = entity.getProperty(edmPropertyName);
+ if (property == null) {
+ throw new ODataApplicationException("Property not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
+ }
+
+ // 3. serialize
+ Object value = property.getValue();
+ if (value != null) {
+ // 3.1. configure the serializer
+ ODataFormat format = ODataFormat.fromContentType(responseFormat);
+ ODataSerializer serializer = odata.createSerializer(format);
+
+ ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).navOrPropertyPath(edmPropertyName).build();
+ PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextUrl).build();
+ // 3.2. serialize
+ SerializerResult serializerResult = serializer.primitive(edmPropertyType, property, options);
+ InputStream propertyStream = serializerResult.getContent();
+
+ //4. configure the response object
+ response.setContent(propertyStream);
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
+ } else {
+ // in case there's no value for the property, we can skip the serialization
+ response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+ }
+ }
+
+
+
+ /*
+ * These processor methods are not handled in this tutorial
+ * */
+
+ public void updatePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo,
+ ContentType requestFormat, ContentType responseFormat)
+ throws ODataApplicationException, DeserializerException, SerializerException {
+ throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+
+ public void deletePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo)
+ throws ODataApplicationException {
+ throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/util/Util.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/util/Util.java b/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/util/Util.java
new file mode 100755
index 0000000..c21d352
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/util/Util.java
@@ -0,0 +1,105 @@
+/*
+ * 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 myservice.mynamespace.util;
+
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntityCollection;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmType;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
+import org.apache.olingo.server.api.ODataApplicationException;
+import org.apache.olingo.server.api.uri.UriInfoResource;
+import org.apache.olingo.server.api.uri.UriParameter;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+
+public class Util {
+
+ public static Entity findEntity(EdmEntityType edmEntityType, EntityCollection entitySet,
+ List<UriParameter> keyParams) throws ODataApplicationException {
+
+ List<Entity> entityList = entitySet.getEntities();
+
+ // loop over all entities in order to find that one that matches all keys in request
+ // e.g. contacts(ContactID=1, CompanyID=1)
+ for (Entity entity: entityList) {
+ boolean foundEntity = entityMatchesAllKeys(edmEntityType, entity, keyParams);
+ if (foundEntity) {
+ return entity;
+ }
+ }
+
+ return null;
+ }
+
+ public static boolean entityMatchesAllKeys(EdmEntityType edmEntityType, Entity entity, List<UriParameter> keyParams)
+ throws ODataApplicationException {
+
+ // loop over all keys
+ for (final UriParameter key : keyParams) {
+ // key
+ String keyName = key.getName();
+ String keyText = key.getText();
+
+ // Edm: we need this info for the comparison below
+ EdmProperty edmKeyProperty = (EdmProperty) edmEntityType.getProperty(keyName);
+ Boolean isNullable = edmKeyProperty.isNullable();
+ Integer maxLength = edmKeyProperty.getMaxLength();
+ Integer precision = edmKeyProperty.getPrecision();
+ Boolean isUnicode = edmKeyProperty.isUnicode();
+ Integer scale = edmKeyProperty.getScale();
+ // get the EdmType in order to compare
+ EdmType edmType = edmKeyProperty.getType();
+ EdmPrimitiveType edmPrimitiveType = (EdmPrimitiveType) edmType;
+
+ // Runtime data: the value of the current entity
+ // don't need to check for null, this is done in olingo library
+ Object valueObject = entity.getProperty(keyName).getValue();
+
+ // now need to compare the valueObject with the keyText String
+ // this is done using the type.valueToString
+ String valueAsString;
+ try {
+ valueAsString = edmPrimitiveType.valueToString(valueObject, isNullable, maxLength, precision, scale, isUnicode);
+ } catch (EdmPrimitiveTypeException e) {
+ throw new ODataApplicationException("Failed to retrieve String value", HttpStatusCode.INTERNAL_SERVER_ERROR
+ .getStatusCode(), Locale.ENGLISH, e);
+ }
+
+ if (valueAsString == null) {
+ return false;
+ }
+
+ boolean matches = valueAsString.equals(keyText);
+ if (!matches) {
+ // if any of the key properties is not found in the entity, we don't need to search further
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/web/DemoServlet.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/web/DemoServlet.java b/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/web/DemoServlet.java
new file mode 100755
index 0000000..fe5cdbb
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions-tis/src/main/java/myservice/mynamespace/web/DemoServlet.java
@@ -0,0 +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 myservice.mynamespace.web;
+
+import java.io.IOException;
+import java.lang.Override;import java.lang.RuntimeException;import java.util.ArrayList;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import myservice.mynamespace.data.Storage;
+import myservice.mynamespace.service.DemoEdmProvider;
+import myservice.mynamespace.service.DemoEntityCollectionProcessor;
+import myservice.mynamespace.service.DemoEntityProcessor;
+import myservice.mynamespace.service.DemoPrimitiveProcessor;
+
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataHttpHandler;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.edmx.EdmxReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DemoServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+ private static final Logger LOG = LoggerFactory.getLogger(DemoServlet.class);
+
+
+ @Override
+ protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ try {
+ HttpSession session = req.getSession(true);
+ Storage storage = (Storage) session.getAttribute(Storage.class.getName());
+ if (storage == null) {
+ storage = new Storage();
+ session.setAttribute(Storage.class.getName(), storage);
+ }
+
+ // create odata handler and configure it with EdmProvider and Processor
+ OData odata = OData.newInstance();
+ ServiceMetadata edm = odata.createServiceMetadata(new DemoEdmProvider(), new ArrayList<EdmxReference>());
+ ODataHttpHandler handler = odata.createHandler(edm);
+ handler.register(new DemoEntityCollectionProcessor(storage));
+ handler.register(new DemoEntityProcessor(storage));
+ handler.register(new DemoPrimitiveProcessor(storage));
+
+ // let the handler do the work
+ handler.process(req, resp);
+ } catch (RuntimeException e) {
+ LOG.error("Server Error occurred in ExampleServlet", e);
+ throw new ServletException(e);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions-tis/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions-tis/src/main/webapp/WEB-INF/web.xml b/samples/tutorials/p5_queryoptions-tis/src/main/webapp/WEB-INF/web.xml
new file mode 100755
index 0000000..21de52a
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions-tis/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,40 @@
+<?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.
+-->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ id="WebApp_ID" version="2.5">
+
+ <!-- Register the HttpServlet implementation -->
+ <servlet>
+ <servlet-name>DemoServlet</servlet-name>
+ <servlet-class>myservice.mynamespace.web.DemoServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <!--
+ Our OData service can be invoked at
+ http://localhost:8080/DemoService/DemoService.svc
+ -->
+ <servlet-mapping>
+ <servlet-name>DemoServlet</servlet-name>
+ <url-pattern>/DemoService.svc/*</url-pattern>
+ </servlet-mapping>
+</web-app>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions-tis/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions-tis/src/main/webapp/index.jsp b/samples/tutorials/p5_queryoptions-tis/src/main/webapp/index.jsp
new file mode 100755
index 0000000..7ffb4ba
--- /dev/null
+++ b/samples/tutorials/p5_queryoptions-tis/src/main/webapp/index.jsp
@@ -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.
+
+-->
+<html>
+<body>
+<h2>Hello World!</h2>
+<a href="DemoService.svc/">OData Olingo V4 Demo Service</a>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions/pom.xml
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/pom.xml b/samples/tutorials/p5_queryoptions/pom.xml
deleted file mode 100755
index 117f59d..0000000
--- a/samples/tutorials/p5_queryoptions/pom.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<?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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>my.group.id</groupId>
- <artifactId>DemoService-QueryOptions</artifactId>
- <packaging>war</packaging>
- <version>0.0.1</version>
-
- <name>${project.artifactId}-Webapp</name>
-
- <build>
- <finalName>DemoService</finalName>
- </build>
-
- <properties>
- <javax.version>2.5</javax.version>
- <odata.version>4.0.0-beta-03</odata.version>
- <slf4j.version>1.7.7</slf4j.version>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- <version>${javax.version}</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>odata-server-api</artifactId>
- <version>${odata.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>odata-server-core</artifactId>
- <version>${odata.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>odata-commons-api</artifactId>
- <version>${odata.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.olingo</groupId>
- <artifactId>odata-commons-core</artifactId>
- <version>${odata.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- <version>${slf4j.version}</version>
- <scope>runtime</scope>
- </dependency>
- </dependencies>
-</project>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/data/Storage.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/data/Storage.java b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/data/Storage.java
deleted file mode 100755
index 2aa9fac..0000000
--- a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/data/Storage.java
+++ /dev/null
@@ -1,130 +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 myservice.mynamespace.data;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-
-import myservice.mynamespace.service.DemoEdmProvider;
-import myservice.mynamespace.util.Util;
-
-import org.apache.olingo.commons.api.data.Entity;
-import org.apache.olingo.commons.api.data.EntityCollection;
-import org.apache.olingo.commons.api.data.Property;
-import org.apache.olingo.commons.api.data.ValueType;
-import org.apache.olingo.commons.api.edm.EdmEntitySet;
-import org.apache.olingo.commons.api.edm.EdmEntityType;
-import org.apache.olingo.commons.api.http.HttpStatusCode;
-import org.apache.olingo.server.api.ODataApplicationException;
-import org.apache.olingo.server.api.uri.UriParameter;
-
-public class Storage {
-
- private List<Entity> productList;
-
- public Storage() {
- productList = new ArrayList<Entity>();
- initSampleData();
- }
-
- /* PUBLIC FACADE */
-
- public EntityCollection readEntitySetData(EdmEntitySet edmEntitySet)throws ODataApplicationException{
-
- // actually, this is only required if we have more than one Entity Sets
- if(edmEntitySet.getName().equals(DemoEdmProvider.ES_PRODUCTS_NAME)){
- return getProducts();
- }
-
- return null;
- }
-
- public Entity readEntityData(EdmEntitySet edmEntitySet, List<UriParameter> keyParams)
- throws ODataApplicationException{
-
- EdmEntityType edmEntityType = edmEntitySet.getEntityType();
-
- // actually, this is only required if we have more than one Entity Type
- if(edmEntityType.getName().equals(DemoEdmProvider.ET_PRODUCT_NAME)){
- return getProduct(edmEntityType, keyParams);
- }
-
- return null;
- }
-
-
-
- /* INTERNAL */
-
- private EntityCollection getProducts(){
- EntityCollection retEntitySet = new EntityCollection();
-
- for(Entity productEntity : this.productList){
- retEntitySet.getEntities().add(productEntity);
- }
-
- return retEntitySet;
- }
-
-
- private Entity getProduct(EdmEntityType edmEntityType, List<UriParameter> keyParams)
- throws ODataApplicationException{
-
- // the list of entities at runtime
- EntityCollection entitySet = getProducts();
-
- /* generic approach to find the requested entity */
- Entity requestedEntity = Util.findEntity(edmEntityType, entitySet, keyParams);
-
- if(requestedEntity == null){
- // this variable is null if our data doesn't contain an entity for the requested key
- // Throw suitable exception
- throw new ODataApplicationException("Entity for requested key doesn't exist",
- HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH);
- }
-
- return requestedEntity;
- }
-
- /* HELPER */
-
- private void initSampleData(){
-
- // add some sample product entities
- productList.add(new Entity()
- .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 1))
- .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Notebook Basic 15"))
- .addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
- "Notebook Basic, 1.7GHz - 15 XGA - 1024MB DDR2 SDRAM - 40GB")));
-
- productList.add(new Entity()
- .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 2))
- .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "1UMTS PDA"))
- .addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
- "Ultrafast 3G UMTS/HSDPA Pocket PC, supports GSM network")));
-
- productList.add(new Entity()
- .addProperty(new Property(null, "ID", ValueType.PRIMITIVE, 3))
- .addProperty(new Property(null, "Name", ValueType.PRIMITIVE, "Ergo Screen"))
- .addProperty(new Property(null, "Description", ValueType.PRIMITIVE,
- "19 Optimum Resolution 1024 x 768 @ 85Hz, resolution 1280 x 960")));
-
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
deleted file mode 100755
index 3c28a21..0000000
--- a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
+++ /dev/null
@@ -1,154 +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 myservice.mynamespace.service;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.olingo.commons.api.ODataException;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
-import org.apache.olingo.commons.api.edm.FullQualifiedName;
-import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
-import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
-import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo;
-import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet;
-import org.apache.olingo.commons.api.edm.provider.CsdlEntityType;
-import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
-import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef;
-import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
-
-public class DemoEdmProvider extends CsdlAbstractEdmProvider {
-
- // Service Namespace
- public static final String NAMESPACE = "OData.Demo";
-
- // EDM Container
- public static final String CONTAINER_NAME = "Container";
- public static final FullQualifiedName CONTAINER = new FullQualifiedName(NAMESPACE, CONTAINER_NAME);
-
- // Entity Types Names
- public static final String ET_PRODUCT_NAME = "Product";
- public static final FullQualifiedName ET_PRODUCT_FQN = new FullQualifiedName(NAMESPACE, ET_PRODUCT_NAME);
-
- // Entity Set Names
- public static final String ES_PRODUCTS_NAME = "Products";
-
- @Override
- public CsdlEntityType getEntityType(FullQualifiedName entityTypeName)
- throws ODataException {
- // this method is called for one of the EntityTypes that are configured in the Schema
- if (ET_PRODUCT_FQN.equals(entityTypeName)) {
-
- // create EntityType properties
- CsdlProperty id = new CsdlProperty().setName("ID").setType(
- EdmPrimitiveTypeKind.Int32.getFullQualifiedName());
- CsdlProperty name = new CsdlProperty().setName("Name").setType(
- EdmPrimitiveTypeKind.String.getFullQualifiedName());
- CsdlProperty description = new CsdlProperty().setName("Description").setType(
- EdmPrimitiveTypeKind.String.getFullQualifiedName());
-
- // create PropertyRef for Key element
- CsdlPropertyRef propertyRef = new CsdlPropertyRef();
- propertyRef.setName("ID");
-
- // configure EntityType
- CsdlEntityType entityType = new CsdlEntityType();
- entityType.setName(ET_PRODUCT_NAME);
- entityType.setProperties(Arrays.asList(id, name, description));
- entityType.setKey(Collections.singletonList(propertyRef));
-
- return entityType;
- }
-
- return null;
-
- }
-
- @Override
- public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer,
- String entitySetName) throws ODataException {
- if (entityContainer.equals(CONTAINER)) {
- if (entitySetName.equals(ES_PRODUCTS_NAME)) {
- CsdlEntitySet entitySet = new CsdlEntitySet();
- entitySet.setName(ES_PRODUCTS_NAME);
- entitySet.setType(ET_PRODUCT_FQN);
-
- return entitySet;
- }
- }
-
- return null;
-
- }
-
- @Override
- public CsdlEntityContainerInfo getEntityContainerInfo(
- FullQualifiedName entityContainerName) throws ODataException {
- // This method is invoked when displaying the service document at
- // e.g. http://localhost:8080/DemoService/DemoService.svc
- if (entityContainerName == null || entityContainerName.equals(CONTAINER)) {
- CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo();
- entityContainerInfo.setContainerName(CONTAINER);
- return entityContainerInfo;
- }
-
- return null;
-
- }
-
- @Override
- public List<CsdlSchema> getSchemas() throws ODataException {
- // create Schema
- CsdlSchema schema = new CsdlSchema();
- schema.setNamespace(NAMESPACE);
-
- // add EntityTypes
- List<CsdlEntityType> entityTypes = new ArrayList<CsdlEntityType>();
- entityTypes.add(getEntityType(ET_PRODUCT_FQN));
- schema.setEntityTypes(entityTypes);
-
- // add EntityContainer
- schema.setEntityContainer(getEntityContainer());
-
- // finally
- List<CsdlSchema> schemas = new ArrayList<CsdlSchema>();
- schemas.add(schema);
-
- return schemas;
-
- }
-
- @Override
- public CsdlEntityContainer getEntityContainer() throws ODataException {
- // create EntitySets
- List<CsdlEntitySet> entitySets = new ArrayList<CsdlEntitySet>();
- entitySets.add(getEntitySet(CONTAINER, ES_PRODUCTS_NAME));
-
- // create EntityContainer
- CsdlEntityContainer entityContainer = new CsdlEntityContainer();
- entityContainer.setName(CONTAINER_NAME);
- entityContainer.setEntitySets(entitySets);
-
- return entityContainer;
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java
deleted file mode 100755
index fc58c23..0000000
--- a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEntityCollectionProcessor.java
+++ /dev/null
@@ -1,142 +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 myservice.mynamespace.service;
-
-import java.io.InputStream;
-import java.util.List;
-import java.util.Locale;
-
-import myservice.mynamespace.data.Storage;
-
-import org.apache.olingo.commons.api.data.ContextURL;
-import org.apache.olingo.commons.api.data.Entity;
-import org.apache.olingo.commons.api.data.EntityCollection;
-import org.apache.olingo.commons.api.edm.EdmEntitySet;
-import org.apache.olingo.commons.api.edm.EdmEntityType;
-import org.apache.olingo.commons.api.format.ContentType;
-import org.apache.olingo.commons.api.format.ODataFormat;
-import org.apache.olingo.commons.api.http.HttpHeader;
-import org.apache.olingo.commons.api.http.HttpStatusCode;
-import org.apache.olingo.server.api.OData;
-import org.apache.olingo.server.api.ODataApplicationException;
-import org.apache.olingo.server.api.ODataRequest;
-import org.apache.olingo.server.api.ODataResponse;
-import org.apache.olingo.server.api.ServiceMetadata;
-import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
-import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
-import org.apache.olingo.server.api.serializer.ODataSerializer;
-import org.apache.olingo.server.api.serializer.SerializerException;
-import org.apache.olingo.server.api.serializer.SerializerResult;
-import org.apache.olingo.server.api.uri.UriInfo;
-import org.apache.olingo.server.api.uri.UriResource;
-import org.apache.olingo.server.api.uri.UriResourceEntitySet;
-import org.apache.olingo.server.api.uri.queryoption.CountOption;
-import org.apache.olingo.server.api.uri.queryoption.SkipOption;
-import org.apache.olingo.server.api.uri.queryoption.TopOption;
-
-public class DemoEntityCollectionProcessor implements EntityCollectionProcessor {
-
- private OData odata;
- private ServiceMetadata serviceMetadata;
- private Storage storage;
-
- public DemoEntityCollectionProcessor(Storage storage) {
- this.storage = storage;
- }
-
- public void init(OData odata, ServiceMetadata serviceMetadata) {
- this.odata = odata;
- this.serviceMetadata = serviceMetadata;
- }
-
- public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo,
- ContentType responseFormat) throws ODataApplicationException, SerializerException {
-
- // 1st retrieve the requested EntitySet from the uriInfo (representation of the parsed URI)
- List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
- // in our example, the first segment is the EntitySet
- UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
- EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
-
- // 2nd: fetch the data from backend for this requested EntitySetName and deliver as EntitySet
- EntityCollection entityCollection = storage.readEntitySetData(edmEntitySet);
-
- // 3rd: apply System Query Options
- // modify the result set according to the query options, specified by the end user
- List<Entity> entityList = entityCollection.getEntities();
- EntityCollection returnEntityCollection = new EntityCollection();
-
- // handle $count: always return the original number of entities, without considering $top and $skip
- CountOption countOption = uriInfo.getCountOption();
- if (countOption != null) {
- boolean isCount = countOption.getValue();
- if (isCount) {
- returnEntityCollection.setCount(entityList.size());
- }
- }
-
- // handle $skip
- SkipOption skipOption = uriInfo.getSkipOption();
- if (skipOption != null) {
- int skipNumber = skipOption.getValue();
- if (skipNumber >= 0 && skipNumber <= entityList.size()) {
- entityList = entityList.subList(skipNumber, entityList.size());
- } else {
- throw new ODataApplicationException("Invalid value for $skip", HttpStatusCode.BAD_REQUEST.getStatusCode(),
- Locale.ROOT);
- }
- }
-
- // handle $top
- TopOption topOption = uriInfo.getTopOption();
- if (topOption != null) {
- int topNumber = topOption.getValue();
- if (topNumber >= 0 && topNumber <= entityList.size()) {
- entityList = entityList.subList(0, topNumber);
- } else {
- throw new ODataApplicationException("Invalid value for $top", HttpStatusCode.BAD_REQUEST.getStatusCode(),
- Locale.ROOT);
- }
- }
-
- // after applying the system query options, create the EntityCollection based on the reduced list
- for (Entity entity : entityList) {
- returnEntityCollection.getEntities().add(entity);
- }
-
- // 4th: create a serializer based on the requested format (json)
- ODataFormat format = ODataFormat.fromContentType(responseFormat);
- ODataSerializer serializer = odata.createSerializer(format);
-
- // and serialize the content: transform from the EntitySet object to InputStream
- EdmEntityType edmEntityType = edmEntitySet.getEntityType();
- ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build();
-
- EntityCollectionSerializerOptions opts =
- EntityCollectionSerializerOptions.with().contextURL(contextUrl).count(countOption).build();
- SerializerResult serializerResult =
- serializer.entityCollection(serviceMetadata, edmEntityType, returnEntityCollection, opts);
- InputStream serializedContent = serializerResult.getContent();
-
- // 5th: configure the response object: set the body, headers and status code
- response.setContent(serializedContent);
- response.setStatusCode(HttpStatusCode.OK.getStatusCode());
- response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java
deleted file mode 100755
index 81453a0..0000000
--- a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoEntityProcessor.java
+++ /dev/null
@@ -1,118 +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 myservice.mynamespace.service;
-
-import java.io.InputStream;
-import java.util.List;
-import java.util.Locale;
-
-import myservice.mynamespace.data.Storage;
-
-import org.apache.olingo.commons.api.data.ContextURL;
-import org.apache.olingo.commons.api.data.Entity;
-import org.apache.olingo.commons.api.edm.EdmEntitySet;
-import org.apache.olingo.commons.api.edm.EdmEntityType;
-import org.apache.olingo.commons.api.format.ContentType;
-import org.apache.olingo.commons.api.format.ODataFormat;
-import org.apache.olingo.commons.api.http.HttpHeader;
-import org.apache.olingo.commons.api.http.HttpStatusCode;
-import org.apache.olingo.server.api.OData;
-import org.apache.olingo.server.api.ODataApplicationException;
-import org.apache.olingo.server.api.ODataRequest;
-import org.apache.olingo.server.api.ODataResponse;
-import org.apache.olingo.server.api.ServiceMetadata;
-import org.apache.olingo.server.api.deserializer.DeserializerException;
-import org.apache.olingo.server.api.processor.EntityProcessor;
-import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
-import org.apache.olingo.server.api.serializer.ODataSerializer;
-import org.apache.olingo.server.api.serializer.SerializerException;
-import org.apache.olingo.server.api.serializer.SerializerResult;
-import org.apache.olingo.server.api.uri.UriInfo;
-import org.apache.olingo.server.api.uri.UriParameter;
-import org.apache.olingo.server.api.uri.UriResource;
-import org.apache.olingo.server.api.uri.UriResourceEntitySet;
-
-public class DemoEntityProcessor implements EntityProcessor {
-
- private OData odata;
- private ServiceMetadata serviceMetadata;
- private Storage storage;
-
- public DemoEntityProcessor(Storage storage) {
- this.storage = storage;
- }
-
- public void init(OData odata, ServiceMetadata serviceMetadata) {
- this.odata = odata;
- this.serviceMetadata = serviceMetadata;
- }
-
- public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
- throws ODataApplicationException, SerializerException {
-
- // 1. retrieve the Entity Type
- List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
- // Note: only in our example we can assume that the first segment is the EntitySet
- UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
- EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
-
- // 2. retrieve the data from backend
- List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
- Entity entity = storage.readEntityData(edmEntitySet, keyPredicates);
-
- // 3. serialize
- EdmEntityType entityType = edmEntitySet.getEntityType();
-
- ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).suffix(ContextURL.Suffix.ENTITY).build();
- // expand and select currently not supported
- EntitySerializerOptions options = EntitySerializerOptions.with().contextURL(contextUrl).build();
-
- ODataFormat oDataFormat = ODataFormat.fromContentType(responseFormat);
- ODataSerializer serializer = this.odata.createSerializer(oDataFormat);
- SerializerResult serializerResult = serializer.entity(serviceMetadata, entityType, entity, options);
- InputStream entityStream = serializerResult.getContent();
-
- // 4. configure the response object
- response.setContent(entityStream);
- response.setStatusCode(HttpStatusCode.OK.getStatusCode());
- response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
- }
-
- /*
- * These processor methods are not handled in this tutorial
- */
-
- public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat,
- ContentType responseFormat)
- throws ODataApplicationException, DeserializerException, SerializerException {
- throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
- }
-
- public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat,
- ContentType responseFormat)
- throws ODataApplicationException, DeserializerException, SerializerException {
- throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
- }
-
- public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo)
- throws ODataApplicationException {
- throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b477bde0/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java b/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java
deleted file mode 100755
index 64f7949..0000000
--- a/samples/tutorials/p5_queryoptions/src/main/java/myservice/mynamespace/service/DemoPrimitiveProcessor.java
+++ /dev/null
@@ -1,150 +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 myservice.mynamespace.service;
-
-import java.io.InputStream;
-import java.util.List;
-import java.util.Locale;
-
-import myservice.mynamespace.data.Storage;
-
-import org.apache.olingo.commons.api.data.ContextURL;
-import org.apache.olingo.commons.api.data.Entity;
-import org.apache.olingo.commons.api.data.Property;
-import org.apache.olingo.commons.api.edm.EdmEntitySet;
-import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
-import org.apache.olingo.commons.api.edm.EdmProperty;
-import org.apache.olingo.commons.api.format.ContentType;
-import org.apache.olingo.commons.api.format.ODataFormat;
-import org.apache.olingo.commons.api.http.HttpHeader;
-import org.apache.olingo.commons.api.http.HttpStatusCode;
-import org.apache.olingo.server.api.OData;
-import org.apache.olingo.server.api.ODataApplicationException;
-import org.apache.olingo.server.api.ODataRequest;
-import org.apache.olingo.server.api.ODataResponse;
-import org.apache.olingo.server.api.ServiceMetadata;
-import org.apache.olingo.server.api.deserializer.DeserializerException;
-import org.apache.olingo.server.api.processor.PrimitiveProcessor;
-import org.apache.olingo.server.api.serializer.ODataSerializer;
-import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
-import org.apache.olingo.server.api.serializer.SerializerException;
-import org.apache.olingo.server.api.serializer.SerializerResult;
-import org.apache.olingo.server.api.uri.UriInfo;
-import org.apache.olingo.server.api.uri.UriParameter;
-import org.apache.olingo.server.api.uri.UriResource;
-import org.apache.olingo.server.api.uri.UriResourceEntitySet;
-import org.apache.olingo.server.api.uri.UriResourceProperty;
-
-public class DemoPrimitiveProcessor implements PrimitiveProcessor {
-
- private OData odata;
- private Storage storage;
-
- public DemoPrimitiveProcessor(Storage storage) {
- this.storage = storage;
- }
-
- public void init(OData odata, ServiceMetadata serviceMetadata) {
- this.odata = odata;
-
- }
-
- /*
- * In our example, the URL would be: http://localhost:8080/DemoService/DemoService.svc/Products(1)/Name
- * and the response:
- * {
- * @odata.context: "$metadata#Products/Name",
- * value: "Notebook Basic 15"
- * }
- * */
- public void readPrimitive(ODataRequest request, ODataResponse response,
- UriInfo uriInfo, ContentType responseFormat)
- throws ODataApplicationException, SerializerException {
-
- // 1. Retrieve info from URI
- // 1.1. retrieve the info about the requested entity set
- List<UriResource> resourceParts = uriInfo.getUriResourceParts();
- // Note: only in our example we can rely that the first segment is the EntitySet
- UriResourceEntitySet uriEntityset = (UriResourceEntitySet) resourceParts.get(0);
- EdmEntitySet edmEntitySet = uriEntityset.getEntitySet();
- // the key for the entity
- List<UriParameter> keyPredicates = uriEntityset.getKeyPredicates();
-
- // 1.2. retrieve the requested (Edm) property
- // the last segment is the Property
- UriResourceProperty uriProperty = (UriResourceProperty)resourceParts.get(resourceParts.size() -1);
- EdmProperty edmProperty = uriProperty.getProperty();
- String edmPropertyName = edmProperty.getName();
- // in our example, we know we have only primitive types in our model
- EdmPrimitiveType edmPropertyType = (EdmPrimitiveType) edmProperty.getType();
-
-
- // 2. retrieve data from backend
- // 2.1. retrieve the entity data, for which the property has to be read
- Entity entity = storage.readEntityData(edmEntitySet, keyPredicates);
- if (entity == null) { // Bad request
- throw new ODataApplicationException("Entity not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
- }
-
- // 2.2. retrieve the property data from the entity
- Property property = entity.getProperty(edmPropertyName);
- if (property == null) {
- throw new ODataApplicationException("Property not found", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
- }
-
- // 3. serialize
- Object value = property.getValue();
- if (value != null) {
- // 3.1. configure the serializer
- ODataFormat format = ODataFormat.fromContentType(responseFormat);
- ODataSerializer serializer = odata.createSerializer(format);
-
- ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).navOrPropertyPath(edmPropertyName).build();
- PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextUrl).build();
- // 3.2. serialize
- SerializerResult serializerResult = serializer.primitive(edmPropertyType, property, options);
- InputStream propertyStream = serializerResult.getContent();
-
- //4. configure the response object
- response.setContent(propertyStream);
- response.setStatusCode(HttpStatusCode.OK.getStatusCode());
- response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
- } else {
- // in case there's no value for the property, we can skip the serialization
- response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
- }
- }
-
-
-
- /*
- * These processor methods are not handled in this tutorial
- * */
-
- public void updatePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo,
- ContentType requestFormat, ContentType responseFormat)
- throws ODataApplicationException, DeserializerException, SerializerException {
- throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
- }
-
- public void deletePrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo)
- throws ODataApplicationException {
- throw new ODataApplicationException("Not supported.", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
- }
-}
[07/18] olingo-odata4 git commit: [OLINGO-731] Added html as debug
output and refactored structure
Posted by ch...@apache.org.
[OLINGO-731] Added html as debug output and refactored structure
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/3dae763f
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/3dae763f
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/3dae763f
Branch: refs/heads/OLINGO-640
Commit: 3dae763f359b27c4c2d13dd95193dc4f76e778ab
Parents: 010d94f
Author: Christian Amend <ch...@sap.com>
Authored: Fri Jul 24 16:11:13 2015 +0200
Committer: Christian Amend <ch...@sap.com>
Committed: Fri Jul 24 16:12:01 2015 +0200
----------------------------------------------------------------------
.../apache/olingo/server/api/ODataResponse.java | 2 +-
.../server/api/debug/DebugInformation.java | 118 ++++++++++
.../server/api/debug/DebugResponseHelper.java | 7 +-
.../olingo/server/api/debug/DebugSupport.java | 10 +-
.../server/api/debug/DefaultDebugSupport.java | 17 +-
.../apache/olingo/server/core/ODataHandler.java | 10 +-
.../server/core/ODataHttpHandlerImpl.java | 89 ++-----
.../olingo/server/core/debug/DebugInfo.java | 50 ----
.../olingo/server/core/debug/DebugInfoBody.java | 150 ------------
.../server/core/debug/DebugInfoException.java | 142 ------------
.../server/core/debug/DebugInfoRequest.java | 112 ---------
.../server/core/debug/DebugInfoResponse.java | 87 -------
.../server/core/debug/DebugInfoRuntime.java | 186 ---------------
.../server/core/debug/DebugInfoServer.java | 87 -------
.../olingo/server/core/debug/DebugInfoUri.java | 231 ------------------
.../core/debug/DebugResponseHelperImpl.java | 229 +++++++++---------
.../olingo/server/core/debug/DebugTab.java | 50 ++++
.../olingo/server/core/debug/DebugTabBody.java | 149 ++++++++++++
.../server/core/debug/DebugTabException.java | 136 +++++++++++
.../server/core/debug/DebugTabRequest.java | 115 +++++++++
.../server/core/debug/DebugTabResponse.java | 89 +++++++
.../server/core/debug/DebugTabRuntime.java | 181 +++++++++++++++
.../server/core/debug/DebugTabServer.java | 57 +++++
.../olingo/server/core/debug/DebugTabUri.java | 232 +++++++++++++++++++
.../server/core/debug/ServerCoreDebugger.java | 137 +++++++++++
.../olingo/server/tecsvc/TechnicalServlet.java | 1 -
.../olingo/server/core/ODataHandlerTest.java | 10 +-
27 files changed, 1423 insertions(+), 1261 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java
index 493e794..7b9e9c9 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataResponse.java
@@ -31,7 +31,7 @@ import org.apache.olingo.commons.api.http.HttpStatusCode;
public class ODataResponse {
private int statusCode = HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode();
- private Map<String, String> headers = new HashMap<String, String>();
+ private final Map<String, String> headers = new HashMap<String, String>();
private InputStream content;
/**
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugInformation.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugInformation.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugInformation.java
new file mode 100644
index 0000000..9198c6b
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugInformation.java
@@ -0,0 +1,118 @@
+/*
+ * 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.server.api.debug;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.olingo.server.api.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.uri.UriInfo;
+
+/**
+ * This class contains all information necessary to construct a debug response.
+ */
+public class DebugInformation {
+
+ private ODataRequest request;
+ private ODataResponse applicationResponse;
+ private UriInfo uriInfo;
+ private Exception exception;
+ private Map<String, String> serverEnvironmentVaribles;
+ private List<RuntimeMeasurement> runtimeInformation;
+
+ /**
+ * This method will return the ODataRequest the library created. This request will never be null but might be filled
+ * incompletely if there has been an exception during the request parsing.
+ * @return the ODataRequest the library built
+ */
+ public ODataRequest getRequest() {
+ return request;
+ }
+
+ public void setRequest(ODataRequest request) {
+ this.request = request;
+ }
+
+ /**
+ * This method will return the ODataResponse which was filled by the Application or the library in an exception case.
+ * The response might be null or might not be filled completely.
+ * @return the response filled by the application
+ */
+ public ODataResponse getApplicationResponse() {
+ return applicationResponse;
+ }
+
+ public void setApplicationResponse(ODataResponse applicationResponse) {
+ this.applicationResponse = applicationResponse;
+ }
+
+ /**
+ * The URI Info object the library created during URI parsing. Might be null if there was an exception during URI
+ * parsing.
+ * @return the URI Info Object
+ */
+ public UriInfo getUriInfo() {
+ return uriInfo;
+ }
+
+ public void setUriInfo(UriInfo uriInfo) {
+ this.uriInfo = uriInfo;
+ }
+
+ /**
+ * This method will return any exception that was thrown from the application or library. Will be null if there was no
+ * exception.
+ * @return an exception if thrown.
+ */
+ public Exception getException() {
+ return exception;
+ }
+
+ public void setException(Exception exception) {
+ this.exception = exception;
+ }
+
+ /**
+ * A map containing information about the runtime environment. Depending on the servlet or webserver used this map
+ * might contain different information. Will never be null but might be empty.
+ * @return environment variables
+ */
+ public Map<String, String> getServerEnvironmentVaribles() {
+ return serverEnvironmentVaribles;
+ }
+
+ public void setServerEnvironmentVaribles(Map<String, String> serverEnvironmentVaribles) {
+ this.serverEnvironmentVaribles = serverEnvironmentVaribles;
+ }
+
+ /**
+ * This method will return all runtime information which was collected inside the library. Might be null if no data
+ * could be collected.
+ * @return runtime information collected by the library
+ */
+ public List<RuntimeMeasurement> getRuntimeInformation() {
+ return runtimeInformation;
+ }
+
+ public void setRuntimeInformation(List<RuntimeMeasurement> runtimeInformation) {
+ this.runtimeInformation = runtimeInformation;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java
index bf6fc56..e2f6933 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugResponseHelper.java
@@ -18,10 +18,6 @@
*/
package org.apache.olingo.server.api.debug;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
/**
@@ -38,6 +34,5 @@ public interface DebugResponseHelper {
* @param runtimeInformation
* @return the debug response or the raw application response in case an exception occurred.
*/
- ODataResponse createDebugResponse(ODataRequest request, ODataResponse applicationResponse, Exception exception,
- Map<String, String> serverEnvironmentVaribles, List<RuntimeMeasurement> runtimeInformation);
+ ODataResponse createDebugResponse(DebugInformation debugInfo);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java
index 995ba34..7a94c44 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DebugSupport.java
@@ -18,11 +18,7 @@
*/
package org.apache.olingo.server.api.debug;
-import java.util.List;
-import java.util.Map;
-
import org.apache.olingo.server.api.OData;
-import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
/**
@@ -35,8 +31,11 @@ public interface DebugSupport {
public static final String ODATA_DEBUG_HTML = "html";
public static final String ODATA_DEBUG_DOWNLOAD = "download";
+ //TODO:JavaDoc
void init(OData odata);
+ boolean isUserAuthorized();
+
/**
* This method should create a debug response and deliver it back to the Olingo library. This method MUST NEVER throw
* an exception.
@@ -46,7 +45,6 @@ public interface DebugSupport {
* @param exception which has been thrown. Might be null in case there was no exception
* @return a new debug response which will be send to the client
*/
- ODataResponse createDebugResponse(String debugFormat, ODataRequest request, ODataResponse response,
- Exception exception, Map<String, String> serverEnvironmentVaribles, List<RuntimeMeasurement> runtimeInformation);
+ ODataResponse createDebugResponse(String debugFormat, DebugInformation debugInfo);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java
index cca537f..7079e76 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/debug/DefaultDebugSupport.java
@@ -18,11 +18,7 @@
*/
package org.apache.olingo.server.api.debug;
-import java.util.List;
-import java.util.Map;
-
import org.apache.olingo.server.api.OData;
-import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
/**
@@ -38,18 +34,21 @@ public class DefaultDebugSupport implements DebugSupport {
}
@Override
- public ODataResponse createDebugResponse(String debugFormat, ODataRequest request, ODataResponse applicationResponse,
- Exception exception, Map<String, String> serverEnvironmentVaribles, List<RuntimeMeasurement> runtimeInformation) {
+ public boolean isUserAuthorized() {
+ return true;
+ }
+
+ @Override
+ public ODataResponse createDebugResponse(String debugFormat, DebugInformation debugInfo) {
// Check if debugFormat is supported by the library
if (DebugSupport.ODATA_DEBUG_JSON.equalsIgnoreCase(debugFormat)
|| DebugSupport.ODATA_DEBUG_HTML.equalsIgnoreCase(debugFormat)
|| DebugSupport.ODATA_DEBUG_DOWNLOAD.equalsIgnoreCase(debugFormat)) {
- return odata.createDebugResponseHelper(debugFormat).createDebugResponse(request, applicationResponse, exception,
- serverEnvironmentVaribles, runtimeInformation);
+ return odata.createDebugResponseHelper(debugFormat).createDebugResponse(debugInfo);
} else {
// Debug format is not supported by the library by default so in order to avoid an exception we will just give
// back the original response from the application.
- return applicationResponse;
+ return debugInfo.getApplicationResponse();
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
index 1a0df8d..1d1b270 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
@@ -42,6 +42,7 @@ import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
import org.apache.olingo.server.api.serializer.RepresentationType;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.core.debug.ServerCoreDebugger;
import org.apache.olingo.server.core.uri.parser.Parser;
import org.apache.olingo.server.core.uri.parser.UriParserException;
import org.apache.olingo.server.core.uri.parser.UriParserSemanticException;
@@ -54,15 +55,18 @@ public class ODataHandler {
private final OData odata;
private final ServiceMetadata serviceMetadata;
private final List<Processor> processors = new LinkedList<Processor>();
+ private final ServerCoreDebugger debugger;
+
private CustomContentTypeSupport customContentTypeSupport;
private CustomETagSupport customETagSupport;
private UriInfo uriInfo;
private Exception lastThrownException;
- public ODataHandler(final OData server, final ServiceMetadata serviceMetadata) {
+ public ODataHandler(final OData server, final ServiceMetadata serviceMetadata, ServerCoreDebugger debugger) {
odata = server;
this.serviceMetadata = serviceMetadata;
+ this.debugger = debugger;
register(new DefaultRedirectProcessor());
register(new DefaultProcessor());
@@ -192,4 +196,8 @@ public class ODataHandler {
public Exception getLastThrownException() {
return lastThrownException;
}
+
+ public UriInfo getUriInfo(){
+ return uriInfo;
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
index 2bab186..e443591 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
@@ -35,19 +35,19 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod;
-import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataHttpHandler;
+import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
-import org.apache.olingo.server.api.ODataLibraryException;
+import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.debug.DebugSupport;
-import org.apache.olingo.server.api.debug.RuntimeMeasurement;
import org.apache.olingo.server.api.etag.CustomETagSupport;
import org.apache.olingo.server.api.processor.Processor;
import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.core.debug.ServerCoreDebugger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,99 +56,52 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
private static final Logger LOG = LoggerFactory.getLogger(ODataHttpHandlerImpl.class);
private final ODataHandler handler;
- private final OData odata;
- private int split = 0;
+ private final ServerCoreDebugger debugger;
- // debug stuff
- private final List<RuntimeMeasurement> runtimeInformation = new ArrayList<RuntimeMeasurement>();
- private DebugSupport debugSupport;
- private String debugFormat;
- private boolean isDebugMode = false;
+ private int split = 0;
public ODataHttpHandlerImpl(final OData odata, final ServiceMetadata serviceMetadata) {
- this.odata = odata;
- handler = new ODataHandler(odata, serviceMetadata);
+ debugger = new ServerCoreDebugger(odata);
+ handler = new ODataHandler(odata, serviceMetadata, debugger);
}
@Override
public void process(final HttpServletRequest request, final HttpServletResponse response) {
+ ODataRequest odRequest = new ODataRequest();
Exception exception = null;
- ODataRequest odRequest = null;
ODataResponse odResponse;
- resolveDebugMode(request);
- int processMethodHandel = startRuntimeMeasurement("ODataHttpHandlerImpl", "process");
+ debugger.resolveDebugMode(request);
+ int processMethodHandel = debugger.startRuntimeMeasurement("ODataHttpHandlerImpl", "process");
try {
- odRequest = new ODataRequest();
- int requestHandel = startRuntimeMeasurement("ODataHttpHandlerImpl", "fillODataRequest");
+ int requestHandel = debugger.startRuntimeMeasurement("ODataHttpHandlerImpl", "fillODataRequest");
fillODataRequest(odRequest, request, split);
- stopRuntimeMeasurement(requestHandel);
-
- int responseHandel = startRuntimeMeasurement("ODataHandler", "process");
+ debugger.stopRuntimeMeasurement(requestHandel);
+
+ int responseHandel = debugger.startRuntimeMeasurement("ODataHandler", "process");
odResponse = handler.process(odRequest);
- stopRuntimeMeasurement(responseHandel);
+ debugger.stopRuntimeMeasurement(responseHandel);
// ALL future methods after process must not throw exceptions!
} catch (Exception e) {
exception = e;
odResponse = handleException(odRequest, e);
}
- stopRuntimeMeasurement(processMethodHandel);
+ debugger.stopRuntimeMeasurement(processMethodHandel);
- if (isDebugMode) {
- debugSupport.init(odata);
- // TODO: Should we be more careful here with response assignement in order to not loose the original response?
- // TODO: How should we react to exceptions here?
+ if (debugger.isDebugMode()) {
+ Map<String, String> serverEnvironmentVaribles = createEnvironmentVariablesMap(request);
if (exception == null) {
// This is to ensure that we have access to the thrown OData Exception
- // TODO: Should we make this hack
exception = handler.getLastThrownException();
}
- Map<String, String> serverEnvironmentVaribles = createEnvironmentVariablesMap(request);
-
odResponse =
- debugSupport.createDebugResponse(debugFormat, odRequest, odResponse, exception, serverEnvironmentVaribles,
- runtimeInformation);
+ debugger.createDebugResponse(request, exception, odRequest, odResponse, handler.getUriInfo(),
+ serverEnvironmentVaribles);
}
convertToHttp(response, odResponse);
}
- private void resolveDebugMode(HttpServletRequest request) {
- if (debugSupport != null) {
- // Should we read the parameter from the servlet here and ignore multiple parameters?
- debugFormat = request.getParameter(DebugSupport.ODATA_DEBUG_QUERY_PARAMETER);
- // Debug format is present and we have a debug support processor registered so we are in debug mode
- isDebugMode = debugFormat != null;
- }
- }
-
- public int startRuntimeMeasurement(final String className, final String methodName) {
- if (isDebugMode) {
- int handleId = runtimeInformation.size();
-
- final RuntimeMeasurement measurement = new RuntimeMeasurement();
- measurement.setTimeStarted(System.nanoTime());
- measurement.setClassName(className);
- measurement.setMethodName(methodName);
-
- runtimeInformation.add(measurement);
-
- return handleId;
- } else {
- return 0;
- }
- }
-
- public void stopRuntimeMeasurement(final int handle) {
- if (isDebugMode && handle < runtimeInformation.size()) {
- long stopTime = System.nanoTime();
- RuntimeMeasurement runtimeMeasurement = runtimeInformation.get(handle);
- if (runtimeMeasurement != null) {
- runtimeMeasurement.setTimeStopped(stopTime);
- }
- }
- }
-
private Map<String, String> createEnvironmentVariablesMap(HttpServletRequest request) {
LinkedHashMap<String, String> environment = new LinkedHashMap<String, String>();
environment.put("authType", request.getAuthType());
@@ -350,6 +303,6 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
@Override
public void register(final DebugSupport debugSupport) {
- this.debugSupport = debugSupport;
+ debugger.setDebugSupportProcessor(debugSupport);
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfo.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfo.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfo.java
deleted file mode 100644
index 9c5a1d4..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfo.java
+++ /dev/null
@@ -1,50 +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.server.core.debug;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-
-
-/**
- * Debug information.
- */
-public interface DebugInfo {
-
- /**
- * Gets the name of this debug information part, useful as title.
- * @return the name
- */
- public String getName();
-
- /**
- * Appends the content of this debug information part
- * to the given JSON stream writer.
- * @param jsonGenerator a JSON generator
- */
- public void appendJson(JsonGenerator jsonGenerator) throws IOException;
-
- /**
- * Appends the content of this debug information part to the given writer.
- * @param writer a {@link Writer}
- */
- public void appendHtml(Writer writer) throws IOException;
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoBody.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoBody.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoBody.java
deleted file mode 100644
index e266aae..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoBody.java
+++ /dev/null
@@ -1,150 +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.server.core.debug;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.olingo.commons.api.http.HttpHeader;
-import org.apache.olingo.server.api.ODataResponse;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-
-/**
- * Response body debug information.
- */
-public class DebugInfoBody implements DebugInfo {
-
- private static enum ResponseContent {JSON, XML, TEXT, IMAGE};
-
- private final ODataResponse response;
- private final ResponseContent responseContent;
-
- //private final String serviceRoot;
-// private final boolean isXml;
-// private final boolean isJson;
-// private final boolean isText;
-// private final boolean isImage;
-
- public DebugInfoBody(final ODataResponse response, final String serviceRoot) {
- this.response = response;
- // TODO: make header case insensitive
- final String contentType = response.getHeaders().get(HttpHeader.CONTENT_TYPE);
- //TODO: Differentiate better
- if (contentType != null) {
- responseContent = ResponseContent.JSON;
- } else {
- responseContent = ResponseContent.TEXT;
- }
-// isXml = contentType.contains("xml");
-// isJson = !isXml && contentType.startsWith(HttpContentType.APPLICATION_JSON);
-// isText = isXml || isJson || contentType.startsWith("text/")
-// || contentType.startsWith(HttpContentType.APPLICATION_HTTP)
-// || contentType.startsWith(HttpContentType.MULTIPART_MIXED);
-// isImage = !isText && contentType.startsWith("image/");
- }
-
- @Override
- public String getName() {
- return "Body";
- }
-
-//
- @Override
- public void appendJson(final JsonGenerator gen) throws IOException {
- gen.writeString(getContentString());
- }
-
- private String getContentString() {
- try {
- String contentString;
- switch (responseContent) {
- case IMAGE:
- //TODO: DecodeString as base 64
- contentString = "Currently not supported";
- break;
- case JSON:
- case XML:
- case TEXT:
- default:
- // TODO: Remove IOUtils from core dependency
- contentString = IOUtils.toString(response.getContent(), "UTF-8");
- break;
- }
- return contentString;
- } catch (IOException e) {
- return "Could not parse Body for Debug Output";
- }
- }
-
-//
-// @Override
-// public void appendHtml(final Writer writer) throws IOException {
-// final String body = getContentString();
-// if (isImage) {
-// writer.append("<img src=\"data:").append(response.getContentHeader()).append(";base64,")
-// .append(body)
-// .append("\" />\n");
-// } else {
-// writer.append("<pre class=\"code").append(isXml ? " xml" : isJson ? " json" : "").append("\">\n")
-// .append(isXml || isJson ?
-// addLinks(ODataDebugResponseWrapper.escapeHtml(isXml ? formatXml(body) : formatJson(body)), isXml) :
-// ODataDebugResponseWrapper.escapeHtml(body))
-// .append("</pre>\n");
-// }
-// }
-//
-// private String formatXml(final String xml) throws IOException {
-// try {
-// Transformer transformer = TransformerFactory.newInstance().newTransformer();
-// transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-// transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
-// StreamResult outputTarget = new StreamResult(new StringWriter());
-// transformer.transform(new StreamSource(new StringReader(xml)), outputTarget);
-// return outputTarget.getWriter().toString();
-// } catch (final TransformerException e) {
-// return xml;
-// }
-// }
-//
-// private String formatJson(final String json) {
-// return new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create().toJson(new JsonParser().parse(json));
-// }
-//
-// private String addLinks(final String source, final boolean isXml) {
-// final String debugOption = ODataDebugResponseWrapper.ODATA_DEBUG_QUERY_PARAMETER + "="
-// + ODataDebugResponseWrapper.ODATA_DEBUG_HTML;
-// final String urlPattern = "("
-// + (isXml ? "(?:href|src|base)=" : "\"(?:uri|media_src|edit_media|__next)\":\\p{Space}*")
-// + "\")(.+?)\"";
-// return (isXml ? source.replaceAll("(xmlns(?::\\p{Alnum}+)?=\")(.+?)\"", "$1<span class=\"ns\">$2</span>\"") :
-// source)
-// .replaceAll(urlPattern, "$1<a href=\"" + serviceRoot + "$2?" + debugOption + "\">$2</a>\"")
-// .replaceAll("(<a href=\"" + Pattern.quote(serviceRoot) + ')' + Pattern.quote(serviceRoot), "$1")
-// .replaceAll("<a href=\"(.+?)\\?(.+?)\\?" + debugOption, "<a href=\"$1?$2&" + debugOption)
-// .replaceAll("&amp;", "&");
-// }
-
- @Override
- public void appendHtml(Writer writer) throws IOException {
- // TODO Auto-generated method stub
-
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoException.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoException.java
deleted file mode 100644
index b19252f..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoException.java
+++ /dev/null
@@ -1,142 +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.server.core.debug;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.apache.olingo.server.api.ODataLibraryException;
-import org.apache.olingo.server.api.ODataLibraryException.ODataErrorMessage;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-
-/**
- * Exception debug information.
- */
-public class DebugInfoException implements DebugInfo {
-
- private final Exception exception;
-
- public DebugInfoException(final Exception exception) {
- this.exception = exception;
- }
-
- @Override
- public String getName() {
- return "Stacktrace";
- }
-
- @Override
- public void appendJson(final JsonGenerator gen) throws IOException {
- gen.writeStartObject();
- gen.writeFieldName("exceptions");
- gen.writeStartArray();
- Throwable throwable = exception;
- while (throwable != null) {
- gen.writeStartObject();
- gen.writeStringField("class", throwable.getClass().getCanonicalName());
- gen.writeStringField("message", getMessage(throwable));
- gen.writeFieldName("invocation");
- appendJsonStackTraceElement(gen, throwable.getStackTrace()[0]);
- gen.writeEndObject();
-
- // Get next exception in the cause list
- throwable = throwable.getCause();
- }
- gen.writeEndArray();
-
- gen.writeFieldName("stacktrace");
- gen.writeStartArray();
- for (final StackTraceElement stackTraceElement : exception.getStackTrace()) {
- appendJsonStackTraceElement(gen, stackTraceElement);
- }
- gen.writeEndArray();
-
- gen.writeEndObject();
- }
-
- private String getMessage(final Throwable throwable) {
- String message;
- if (throwable instanceof ODataLibraryException) {
- ODataLibraryException ex = (ODataLibraryException) throwable;
- // We use the default locale
- ODataErrorMessage translatedMessage = ex.getTranslatedMessage(null);
- // We provide the best message we can
- message = translatedMessage.getMessage() == null ? ex.getMessage() : translatedMessage.getMessage();
- } else {
- message = throwable.getMessage();
- }
- return message;
- }
-
- private void appendJsonStackTraceElement(final JsonGenerator gen, final StackTraceElement element)
- throws IOException {
- gen.writeStartObject();
- gen.writeStringField("class", element.getClassName());
- gen.writeStringField("method", element.getMethodName());
- gen.writeStringField("line", Integer.toString(element.getLineNumber()));
- gen.writeEndObject();
- }
-
- @Override
- public void appendHtml(Writer writer) throws IOException {
- // TODO Auto-generated method stub
-
- }
-//
-// @Override
-// public void appendHtml(final Writer writer) throws IOException {
-// appendException(exception, writer);
-// writer.append("<h2>Stacktrace</h2>\n");
-// int count = 0;
-// for (final StackTraceElement stackTraceElement : exception.getStackTrace()) {
-// appendStackTraceElement(stackTraceElement, ++count == 1, count == exception.getStackTrace().length, writer);
-// }
-// }
-//
-// private void appendException(final Throwable throwable, final Writer writer) throws IOException {
-// if (throwable.getCause() != null) {
-// appendException(throwable.getCause(), writer);
-// }
-// final StackTraceElement details = throwable.getStackTrace()[0];
-// writer.append("<h2>").append(throwable.getClass().getCanonicalName()).append("</h2>\n")
-// .append("<p>")
-// .append(ODataDebugResponseWrapper.escapeHtml(getMessageText(throwable)))
-// .append("</p>\n");
-// appendStackTraceElement(details, true, true, writer);
-// }
-//
-// private void appendStackTraceElement(final StackTraceElement stackTraceElement,
-// final boolean isFirst, final boolean isLast, final Writer writer) throws IOException {
-// if (isFirst) {
-// writer.append("<table>\n<thead>\n")
-// .append("<tr>\n<th class=\"name\">Class</th>\n")
-// .append("<th class=\"name\">Method</th>\n")
-// .append("<th class=\"value\">Line number in class</th>\n</tr>\n")
-// .append("</thead>\n<tbody>\n");
-// }
-// writer.append("<tr>\n<td class=\"name\">").append(stackTraceElement.getClassName()).append("</td>\n")
-// .append("<td class=\"name\">").append(stackTraceElement.getMethodName()).append("</td>\n")
-// .append("<td class=\"value\">").append(Integer.toString(stackTraceElement.getLineNumber()))
-// .append("</td>\n</tr>\n");
-// if (isLast) {
-// writer.append("</tbody>\n</table>\n");
-// }
-// }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRequest.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRequest.java
deleted file mode 100644
index e28bbb9..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRequest.java
+++ /dev/null
@@ -1,112 +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.server.core.debug;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.olingo.server.api.ODataRequest;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-
-/**
- * Request debug information.
- */
-public class DebugInfoRequest implements DebugInfo {
-
- private final String method;
- private final String uri;
- private final String protocol;
- private final Map<String, String> headers;
-
- public DebugInfoRequest(ODataRequest request) {
- method = request.getMethod() == null ? "unkown" : request.getMethod().toString();
- uri = request.getRawRequestUri() == null ? "unkown" : request.getRawRequestUri();
- protocol = request.getProtocol() == null ? "unkown" : request.getProtocol();
- // TODO: Should we really wrap the headers here or keep the original structure?
- headers = wrapHeaders(request.getAllHeaders());
- }
-
- private Map<String, String> wrapHeaders(Map<String, List<String>> allHeaders) {
- Map<String, String> localHeaders = new HashMap<String, String>();
- for (Map.Entry<String, List<String>> entry : allHeaders.entrySet()) {
- String value = null;
- if (entry.getValue() != null) {
- value = "";
- boolean first = true;
- for (String valuePart : entry.getValue()) {
- if (!first) {
- value = value + ", ";
- }
- value = value + valuePart;
- }
- }
- }
- return localHeaders;
- }
-
- @Override
- public void appendHtml(final Writer writer) throws IOException {
-// writer.append("<h2>Request Method</h2>\n")
-// .append("<p>").append(method).append("</p>\n")
-// .append("<h2>Request URI</h2>\n")
-// .append("<p>").append(DebugResponseHelperImpl.escapeHtml(uri.toString())).append("</p>\n")
-// .append("<h2>Request Protocol</h2>\n")
-// .append("<p>").append(protocol).append("</p>\n");
-// writer.append("<h2>Request Headers</h2>\n")
-// .append("<table>\n<thead>\n")
-// .append("<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n")
-// .append("</thead>\n<tbody>\n");
-// for (final String name : headers.keySet()) {
-// for (final String value : headers.get(name)) {
-// if (value != null) {
-// writer.append("<tr><td class=\"name\">").append(name).append("</td>")
-// .append("<td class=\"value\">").append(DebugResponseHelperImpl.escapeHtml(value))
-// .append("</td></tr>\n");
-// }
-// }
-// }
-// writer.append("</tbody>\n</table>\n");
- }
-
- @Override
- public String getName() {
- return "Request";
- }
-
- @Override
- public void appendJson(JsonGenerator gen) throws IOException {
- gen.writeStartObject();
- gen.writeStringField("method", method);
-
- gen.writeStringField("uri", uri);
-
- gen.writeStringField("protocol", protocol);
-
- if (!headers.isEmpty()) {
- gen.writeFieldName("headers");
- DebugResponseHelperImpl.appendJsonTable(gen, headers);
- }
-
- gen.writeEndObject();
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoResponse.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoResponse.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoResponse.java
deleted file mode 100644
index 0781d50..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoResponse.java
+++ /dev/null
@@ -1,87 +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.server.core.debug;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Map;
-
-import org.apache.olingo.commons.api.http.HttpStatusCode;
-import org.apache.olingo.server.api.ODataResponse;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-
-/**
- * Response debug information.
- */
-public class DebugInfoResponse implements DebugInfo {
-
- private final ODataResponse response;
- private final String serviceRoot;
- private final HttpStatusCode status;
- private final Map<String, String> headers;
-
- public DebugInfoResponse(final ODataResponse applicationResponse, final String serviceRoot) {
- this.response = applicationResponse;
- this.serviceRoot = serviceRoot;
- status = HttpStatusCode.fromStatusCode(response.getStatusCode());
- headers = response.getHeaders();
- }
-
- @Override
- public String getName() {
- return "Response";
- }
-
- @Override
- public void appendJson(final JsonGenerator gen) throws IOException {
- gen.writeStartObject();
-
- if (status != null) {
- gen.writeFieldName("status");
- gen.writeStartObject();
- gen.writeStringField("code", Integer.toString(status.getStatusCode()));
- gen.writeStringField("info", status.getInfo());
- gen.writeEndObject();
- }
-
- if (headers != null && !headers.isEmpty()) {
- gen.writeFieldName("headers");
- DebugResponseHelperImpl.appendJsonTable(gen, headers);
- }
-
- gen.writeFieldName("body");
- new DebugInfoBody(response, serviceRoot).appendJson(gen);
-
- gen.writeEndObject();
- }
-
- @Override
- public void appendHtml(final Writer writer) throws IOException {
-// writer.append("<h2>Status Code</h2>\n")
-// .append("<p>").append(Integer.toString(status.getStatusCode())).append(' ')
-// .append(status.getInfo()).append("</p>\n")
-// .append("<h2>Response Headers</h2>\n");
-// ODataDebugResponseWrapper.appendHtmlTable(writer, headers);
-// if (response.getContentHeader() != null && response.getEntity() != null) {
-// writer.append("<h2>Response Body</h2>\n");
-// new DebugInfoBody(response, serviceRoot).appendHtml(writer);
-// }
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRuntime.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRuntime.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRuntime.java
deleted file mode 100644
index 2465ce4..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoRuntime.java
+++ /dev/null
@@ -1,186 +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.server.core.debug;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.olingo.server.api.debug.RuntimeMeasurement;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-
-/**
- * Runtime debug information.
- */
-public class DebugInfoRuntime implements DebugInfo {
-
- private final RuntimeNode rootNode;
-
- public DebugInfoRuntime(List<RuntimeMeasurement> runtimeInformation) {
- rootNode = new RuntimeNode();
- for (final RuntimeMeasurement runtimeMeasurement : runtimeInformation) {
- rootNode.add(runtimeMeasurement);
- }
- rootNode.combineRuntimeMeasurements();
- }
-
- @Override
- public String getName() {
- return "Runtime";
- }
-
- @Override
- public void appendJson(JsonGenerator gen) throws IOException {
- appendJsonChildren(gen, rootNode);
- }
-
- private void appendJsonChildren(JsonGenerator gen, RuntimeNode node) throws IOException {
- gen.writeStartArray();
- for (RuntimeNode child : node.children) {
- appendJsonNode(gen, child);
- }
- gen.writeEndArray();
- }
-
- private void appendJsonNode(JsonGenerator gen, RuntimeNode node) throws IOException {
- gen.writeStartObject();
- gen.writeStringField("class", node.className);
- gen.writeStringField("method ", node.methodName);
-
- if (node.timeStopped == 0) {
- gen.writeNullField("duration");
- } else {
- gen.writeStringField("duration", Long.toString((node.timeStopped - node.timeStarted) / 1000));
- gen.writeStringField("unit", "µs");
- }
-
- if (!node.children.isEmpty()) {
- gen.writeFieldName("children");
- appendJsonChildren(gen, node);
- }
-
- gen.writeEndObject();
- }
-
- @Override
- public void appendHtml(Writer writer) throws IOException {
- // TODO Auto-generated method stub
- //
-// @Override
-// public void appendHtml(final Writer writer) throws IOException {
-// appendRuntimeNode(rootNode, "", true, writer);
-// }
-//
-// private void appendRuntimeNode(final RuntimeNode node, final String draw, final boolean isLast, final Writer writer)
-// throws IOException {
-// if (node.className != null) {
-// writer.append("<li>")
-// .append("<span class=\"code\">")
-// .append("<span class=\"draw\">").append(draw)
-// .append(isLast ? "└" : "├").append("─ </span>")
-// .append("<span class=\"class\">").append(node.className).append("</span>.")
-// .append("<span class=\"method\">").append(node.methodName).append("(…)")
-// .append("</span></span>");
-// long time = node.timeStopped == 0 ? 0 : (node.timeStopped - node.timeStarted) / 1000;
-// writer.append("<span class=\"").append(time == 0 ? "null" : "numeric")
-// .append("\" title=\"").append(time == 0 ? "Stop time missing" : "Gross duration")
-// .append("\">").append(time == 0 ? "unfinished" : Long.toString(time) + " µs")
-// .append("</span>\n");
-// }
-// if (!node.children.isEmpty()) {
-// writer.append("<ol class=\"tree\">\n");
-// for (final RuntimeNode childNode : node.children) {
-// appendRuntimeNode(childNode,
-// node.className == null ? draw : draw + (isLast ? " " : "│") + " ",
-// node.children.indexOf(childNode) == node.children.size() - 1,
-// writer);
-// }
-// writer.append("</ol>\n");
-// }
-// if (node.className != null) {
-// writer.append("</li>\n");
-// }
-// }
- }
-
- private class RuntimeNode {
-
- protected String className;
- protected String methodName;
- protected long timeStarted;
- protected long timeStopped;
- protected List<RuntimeNode> children = new ArrayList<RuntimeNode>();
-
- protected RuntimeNode() {
- timeStarted = 0;
- timeStopped = Long.MAX_VALUE;
- }
-
- private RuntimeNode(final RuntimeMeasurement runtimeMeasurement) {
- className = runtimeMeasurement.getClassName();
- methodName = runtimeMeasurement.getMethodName();
- timeStarted = runtimeMeasurement.getTimeStarted();
- timeStopped = runtimeMeasurement.getTimeStopped();
- }
-
- protected boolean add(final RuntimeMeasurement runtimeMeasurement) {
- if (timeStarted <= runtimeMeasurement.getTimeStarted()
- && timeStopped != 0 && timeStopped >= runtimeMeasurement.getTimeStopped()) {
- for (RuntimeNode candidate : children) {
- if (candidate.add(runtimeMeasurement)) {
- return true;
- }
- }
- children.add(new RuntimeNode(runtimeMeasurement));
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Combines runtime measurements with identical class names and method
- * names into one measurement, assuming that they originate from a loop
- * or a similar construct where a summary measurement has been intended.
- */
- protected void combineRuntimeMeasurements() {
- RuntimeNode preceding = null;
- for (Iterator<RuntimeNode> iterator = children.iterator(); iterator.hasNext();) {
- final RuntimeNode child = iterator.next();
- if (preceding != null
- && preceding.timeStopped != 0 && child.timeStopped != 0
- && preceding.timeStopped <= child.timeStarted
- && preceding.children.isEmpty() && child.children.isEmpty()
- && preceding.methodName.equals(child.methodName)
- && preceding.className.equals(child.className)) {
- preceding.timeStarted = child.timeStarted - (preceding.timeStopped - preceding.timeStarted);
- preceding.timeStopped = child.timeStopped;
-
- iterator.remove();
- } else {
- preceding = child;
- child.combineRuntimeMeasurements();
- }
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoServer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoServer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoServer.java
deleted file mode 100644
index e974d03..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoServer.java
+++ /dev/null
@@ -1,87 +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.server.core.debug;
-
-import java.io.IOException;
-import java.io.Writer;
-import java.util.Map;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-
-/**
- * Server debug information.
- */
-public class DebugInfoServer implements DebugInfo {
-
- private final Map<String, String> serverEnvironmentVaribles;
-
- public DebugInfoServer(Map<String, String> serverEnvironmentVaribles) {
- this.serverEnvironmentVaribles = serverEnvironmentVaribles;
- }
-
- @Override
- public String getName() {
- return "Environment";
- }
-
- @Override
- public void appendJson(JsonGenerator gen) throws IOException {
- DebugResponseHelperImpl.appendJsonTable(gen, serverEnvironmentVaribles);
- }
-
- @Override
- public void appendHtml(Writer writer) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
-// private final Map<String, String> environment;
-//
-// public DebugInfoServer(final HttpServletRequest httpServletRequest) {
-// environment = new TreeMap<String, String>();
-// environment.put("authType", httpServletRequest.getAuthType());
-// environment.put("localAddr", httpServletRequest.getLocalAddr());
-// environment.put("localName", httpServletRequest.getLocalName());
-// addInt("localPort", httpServletRequest.getLocalPort());
-// environment.put("pathInfo", httpServletRequest.getPathInfo());
-// environment.put("pathTranslated", httpServletRequest.getPathTranslated());
-// environment.put("remoteAddr", httpServletRequest.getRemoteAddr());
-// environment.put("remoteHost", httpServletRequest.getRemoteHost());
-// addInt("remotePort", httpServletRequest.getRemotePort());
-// environment.put("remoteUser", httpServletRequest.getRemoteUser());
-// environment.put("scheme", httpServletRequest.getScheme());
-// environment.put("serverName", httpServletRequest.getServerName());
-// addInt("serverPort", httpServletRequest.getServerPort());
-// environment.put("servletPath", httpServletRequest.getServletPath());
-// }
-
-// @Override
-// public void appendHtml(final Writer writer) throws IOException {
-// final Package pack = ODataDebugResponseWrapper.class.getPackage();
-// writer.append("<h2>Library Version</h2>\n")
-// .append("<p>").append(pack.getImplementationTitle())
-// .append(" Version ").append(pack.getImplementationVersion()).append("</p>\n")
-// .append("<h2>Server Environment</h2>\n");
-// ODataDebugResponseWrapper.appendHtmlTable(writer, environment);
-// }
-//
-// private void addInt(final String name, final int number) {
-// environment.put(name, number == 0 ? null : Integer.toString(number));
-// }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoUri.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoUri.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoUri.java
deleted file mode 100644
index 2ddeb07..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugInfoUri.java
+++ /dev/null
@@ -1,231 +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.server.core.debug;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import com.fasterxml.jackson.core.JsonGenerator;
-
-
-/**
- * URI parser debug information.
- */
-public class DebugInfoUri implements DebugInfo {
-
- @Override
- public String getName() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public void appendJson(JsonGenerator jsonGenerator) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void appendHtml(Writer writer) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
-// private final UriInfo uriInfo;
-// private final FilterExpression filter;
-// private final OrderByExpression orderBy;
-// private final ExpandSelectTreeNodeImpl expandSelectTree;
-// private final ExpressionParserException exception;
-//
-// public DebugInfoUri(final UriInfo uriInfo, final ExpressionParserException exception) {
-// this.uriInfo = uriInfo;
-// filter = uriInfo == null ? null : uriInfo.getFilter();
-// orderBy = uriInfo == null ? null : uriInfo.getOrderBy();
-// expandSelectTree = uriInfo == null ? null : getExpandSelect();
-// this.exception = exception;
-// }
-//
-// private ExpandSelectTreeNodeImpl getExpandSelect() {
-// try {
-// return uriInfo.getExpand().isEmpty() && uriInfo.getSelect().isEmpty() ? null :
-// new ExpandSelectTreeCreator(uriInfo.getSelect(), uriInfo.getExpand()).create();
-// } catch (final EdmException e) {
-// return null;
-// }
-// }
-//
-// @Override
-// public String getName() {
-// return "URI";
-// }
-//
-// @Override
-// public void appendJson(final JsonStreamWriter jsonStreamWriter) throws IOException {
-// jsonStreamWriter.beginObject();
-//
-// if (exception != null && exception.getFilterTree() != null) {
-// jsonStreamWriter.name("error")
-// .beginObject()
-// .namedStringValue("expression", exception.getFilterTree().getUriLiteral())
-// .endObject();
-// if (filter != null || orderBy != null || expandSelectTree != null) {
-// jsonStreamWriter.separator();
-// }
-// }
-//
-// if (filter != null) {
-// String filterString;
-// try {
-// filterString = (String) filter.accept(new JsonVisitor());
-// } catch (final ExceptionVisitExpression e) {
-// filterString = null;
-// } catch (final ODataApplicationException e) {
-// filterString = null;
-// }
-// jsonStreamWriter.name("filter").unquotedValue(filterString);
-// if (orderBy != null || expandSelectTree != null) {
-// jsonStreamWriter.separator();
-// }
-// }
-//
-// if (orderBy != null) {
-// String orderByString;
-// try {
-// orderByString = (String) orderBy.accept(new JsonVisitor());
-// } catch (final ExceptionVisitExpression e) {
-// orderByString = null;
-// } catch (final ODataApplicationException e) {
-// orderByString = null;
-// }
-// jsonStreamWriter.name("orderby").unquotedValue(orderByString);
-// if (expandSelectTree != null) {
-// jsonStreamWriter.separator();
-// }
-// }
-//
-// if (expandSelectTree != null) {
-// jsonStreamWriter.name("expandSelect").unquotedValue(expandSelectTree.toJsonString());
-// }
-//
-// jsonStreamWriter.endObject();
-// }
-//
-// @Override
-// public void appendHtml(final Writer writer) throws IOException {
-// if (exception != null && exception.getFilterTree() != null) {
-// writer.append("<h2>Expression Information</h2>\n")
-// .append("<pre class=\"code\">").append(exception.getFilterTree().getUriLiteral())
-// .append("</pre>\n");
-// // TODO: filter error position, filter tokens, filter tree
-// }
-// if (filter != null) {
-// writer.append("<h2>Filter</h2>\n")
-// .append("<ul class=\"expr\"><li>");
-// appendExpression(filter.getExpression(), writer);
-// writer.append("</li></ul>\n");
-// }
-// if (orderBy != null) {
-// writer.append("<h2>Orderby</h2>\n")
-// .append(orderBy.getOrdersCount() == 1 ? "<ul" : "<ol").append(" class=\"expr\">\n");
-// for (final OrderExpression order : orderBy.getOrders()) {
-// writer.append("<li>");
-// appendExpression(order.getExpression(), writer);
-// final ExpressionKind kind = order.getExpression().getKind();
-// if (kind == ExpressionKind.PROPERTY || kind == ExpressionKind.LITERAL) {
-// writer.append("<br />");
-// }
-// writer.append("<span class=\"order\">")
-// .append(order.getSortOrder().toString())
-// .append("</span></li>\n");
-// }
-// writer.append(orderBy.getOrdersCount() == 1 ? "</ul" : "</ol").append(">\n");
-// }
-// if (expandSelectTree != null) {
-// writer.append("<h2>Expand/Select</h2>\n");
-// appendExpandSelect(expandSelectTree, writer);
-// }
-// }
-//
-// private void appendExpression(final CommonExpression expression, final Writer writer) throws IOException {
-// final ExpressionKind kind = expression.getKind();
-// writer.append("<span class=\"kind\">")
-// .append(kind.toString())
-// .append("</span> <span class=\"literal\">")
-// .append(kind == ExpressionKind.MEMBER ? ((MemberExpression) expression).getProperty().getUriLiteral() :
-// expression.getUriLiteral())
-// .append("</span>, type <span class=\"type\">")
-// .append(expression.getEdmType().toString())
-// .append("</span>");
-// if (kind == ExpressionKind.UNARY) {
-// writer.append("<ul class=\"expr\"><li>");
-// appendExpression(((UnaryExpression) expression).getOperand(), writer);
-// writer.append("</li></ul>");
-// } else if (kind == ExpressionKind.BINARY) {
-// writer.append("<ol class=\"expr\"><li>");
-// appendExpression(((BinaryExpression) expression).getLeftOperand(), writer);
-// writer.append("</li><li>");
-// appendExpression(((BinaryExpression) expression).getRightOperand(), writer);
-// writer.append("</li></ol>");
-// } else if (kind == ExpressionKind.METHOD) {
-// final MethodExpression methodExpression = (MethodExpression) expression;
-// if (methodExpression.getParameterCount() > 0) {
-// writer.append("<ol class=\"expr\">");
-// for (final CommonExpression parameter : methodExpression.getParameters()) {
-// writer.append("<li>");
-// appendExpression(parameter, writer);
-// writer.append("</li>");
-// }
-// writer.append("</ol>");
-// }
-// } else if (kind == ExpressionKind.MEMBER) {
-// writer.append("<ul class=\"expr\"><li>");
-// appendExpression(((MemberExpression) expression).getPath(), writer);
-// writer.append("</li></ul>");
-// }
-// }
-//
-// private void appendExpandSelect(final ExpandSelectTreeNode expandSelect, final Writer writer) throws IOException {
-// writer.append("<ul class=\"expand\">\n")
-// .append("<li>");
-// if (expandSelect.isAll()) {
-// writer.append("all properties");
-// } else {
-// for (final EdmProperty property : expandSelect.getProperties()) {
-// try {
-// writer.append("property <span class=\"prop\">")
-// .append(property.getName())
-// .append("</span><br />");
-// } catch (final EdmException e) {}
-// }
-// }
-// writer.append("</li>\n");
-// if (!expandSelect.getLinks().isEmpty()) {
-// for (final String name : expandSelect.getLinks().keySet()) {
-// writer.append("<li>link <span class=\"link\">").append(name).append("</span>");
-// final ExpandSelectTreeNode link = expandSelect.getLinks().get(name);
-// if (link != null) {
-// writer.append('\n');
-// appendExpandSelect(link, writer);
-// }
-// writer.append("</li>\n");
-// }
-// }
-// writer.append("</ul>\n");
-// }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java
index 6952018..d99dd4c 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugResponseHelperImpl.java
@@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
+import java.io.Writer;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -32,8 +33,8 @@ import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
-import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.debug.DebugInformation;
import org.apache.olingo.server.api.debug.DebugResponseHelper;
import org.apache.olingo.server.api.debug.DebugSupport;
import org.apache.olingo.server.api.debug.RuntimeMeasurement;
@@ -62,13 +63,10 @@ public class DebugResponseHelperImpl implements DebugResponseHelper {
}
@Override
- public ODataResponse createDebugResponse(ODataRequest request, ODataResponse applicationResponse,
- Exception exception, Map<String, String> serverEnvironmentVaribles, List<RuntimeMeasurement> runtimeInformation) {
-
+ public ODataResponse createDebugResponse(DebugInformation debugInfo) {
try {
- final List<DebugInfo> parts =
- createParts(request, applicationResponse, exception, serverEnvironmentVaribles, runtimeInformation);
-
+ final List<DebugTab> parts = createParts(debugInfo);
+
ODataResponse response = new ODataResponse();
String contentTypeString;
InputStream body;
@@ -78,7 +76,9 @@ public class DebugResponseHelperImpl implements DebugResponseHelper {
+ new Date().toString().replace(' ', '_').replace(':', '.') + ".html");
// Download is the same as html except for the above header
case HTML:
- body = wrapInHtml(parts);
+ String title = debugInfo.getRequest() == null ?
+ "V4 Service" : "V4 Service: " + debugInfo.getRequest().getRawODataPath();
+ body = wrapInHtml(parts, title);
contentTypeString = ContentType.TEXT_HTML.toContentTypeString();
break;
case JSON:
@@ -93,65 +93,58 @@ public class DebugResponseHelperImpl implements DebugResponseHelper {
return response;
} catch (IOException e) {
- // Should not happen
- // TODO: Check what we can do here.
+ // Should not happen. In case it does the library will deliver a default response. So no handling here.
throw new ODataRuntimeException(e);
}
}
- private List<DebugInfo> createParts(ODataRequest request, ODataResponse applicationResponse, Exception exception,
- Map<String, String> serverEnvironmentVaribles, List<RuntimeMeasurement> runtimeInformation) {
- List<DebugInfo> parts = new ArrayList<DebugInfo>();
+ private List<DebugTab> createParts(DebugInformation debugInfo) {
+ List<DebugTab> parts = new ArrayList<DebugTab>();
// request
- parts.add(new DebugInfoRequest(request));
+ parts.add(new DebugTabRequest(debugInfo.getRequest()));
// response
- // TODO: Check service URI
- parts.add(new DebugInfoResponse(applicationResponse, request.getRawBaseUri()));
+ parts.add(new DebugTabResponse(debugInfo.getApplicationResponse(), debugInfo.getRequest().getRawBaseUri()));
// server
+ Map<String, String> serverEnvironmentVaribles = debugInfo.getServerEnvironmentVaribles();
if (serverEnvironmentVaribles != null && !serverEnvironmentVaribles.isEmpty()) {
- parts.add(new DebugInfoServer(serverEnvironmentVaribles));
+ parts.add(new DebugTabServer(serverEnvironmentVaribles));
}
-// // URI
-// Throwable candidate = exception;
-// while (candidate != null && !(candidate instanceof ExpressionParserException)) {
-// candidate = candidate.getCause();
+ // TODO:Enable URIDebugInfo
+ // URI
+// if (uriInfo != null && (uriInfo.getFilterOption() != null || uriInfo.getOrderByOption() != null
+// || uriInfo.getExpandOption() != null || uriInfo.getSelectOption() != null)) {
+// parts.add(new DebugInfoUri(uriInfo));
// }
-// final ExpressionParserException expressionParserException = (ExpressionParserException) candidate;
-// if (uriInfo != null
-// && (uriInfo.getFilter() != null || uriInfo.getOrderBy() != null
-// || !uriInfo.getExpand().isEmpty() || !uriInfo.getSelect().isEmpty())
-// || expressionParserException != null && expressionParserException.getFilterTree() != null) {
-// parts.add(new DebugInfoUri(uriInfo, expressionParserException));
-// }
-//
-// // runtime measurements
+
+ // runtime measurements
+ List<RuntimeMeasurement> runtimeInformation = debugInfo.getRuntimeInformation();
if (runtimeInformation != null && !runtimeInformation.isEmpty()) {
- parts.add(new DebugInfoRuntime(runtimeInformation));
+ parts.add(new DebugTabRuntime(runtimeInformation));
}
-//
-// // exceptions
- if (exception != null) {
- parts.add(new DebugInfoException(exception));
+
+ // exceptions
+ if (debugInfo.getException() != null) {
+ parts.add(new DebugTabException(debugInfo.getException()));
}
return parts;
}
- private InputStream wrapInJson(final List<DebugInfo> parts) throws IOException {
+ private InputStream wrapInJson(final List<DebugTab> parts) throws IOException {
CircleStreamBuffer csb = new CircleStreamBuffer();
JsonGenerator gen = new JsonFactory().createGenerator(csb.getOutputStream(), JsonEncoding.UTF8);
gen.writeStartObject();
- DebugInfo requestInfo = parts.get(0);
+ DebugTab requestInfo = parts.get(0);
// TODO: Should we really translate to lower case here?
gen.writeFieldName(requestInfo.getName().toLowerCase(Locale.ROOT));
requestInfo.appendJson(gen);
- DebugInfo responseInfo = parts.get(1);
+ DebugTab responseInfo = parts.get(1);
gen.writeFieldName(responseInfo.getName().toLowerCase(Locale.ROOT));
responseInfo.appendJson(gen);
@@ -163,7 +156,7 @@ public class DebugResponseHelperImpl implements DebugResponseHelper {
} else {
gen.writeNullField("version");
}
- for (DebugInfo part : parts.subList(2, parts.size())) {
+ for (DebugTab part : parts.subList(2, parts.size())) {
gen.writeFieldName(part.getName().toLowerCase(Locale.ROOT));
part.appendJson(gen);
}
@@ -171,76 +164,72 @@ public class DebugResponseHelperImpl implements DebugResponseHelper {
gen.writeEndObject();
gen.close();
+ csb.close();
return csb.getInputStream();
}
- private InputStream wrapInHtml(final List<DebugInfo> parts) throws IOException {
+ private InputStream wrapInHtml(final List<DebugTab> parts, String title) throws IOException {
StringWriter writer = new StringWriter();
-// PathInfo pathInfo = null;
-// try {
-// pathInfo = context.getPathInfo();
-// } catch (final ODataException e) {}
-//
-// writer.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\n")
-// .append(" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n")
-// .append("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n")
-// .append("<head>\n")
-// .append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n")
-// .append("<title>")
-// .append(pathInfo == null ? "" :
-// escapeHtml(pathInfo.getServiceRoot().relativize(pathInfo.getRequestUri()).getPath()))
-// .append("</title>\n")
-// .append("<style type=\"text/css\">\n")
-// .append("body { font-family: Arial, sans-serif; font-size: 13px;\n")
-// .append(" line-height: 16px; margin: 0;\n")
-// .append(" background-color: #eeeeee; color: #333333; }\n")
-// .append(".header { float: left; }\n")
-// .append(".header a { line-height: 22px; padding: 10px 18px;\n")
-// .append(" text-decoration: none; color: #333333; }\n")
-// .append(":target, .header:nth-last-child(2) { background-color: #cccccc; }\n")
-// .append(":target ~ .header:nth-last-child(2) { background-color: inherit; }\n")
-// .append(".header:focus, .header:hover,\n")
-// .append(" .header:nth-last-child(2):focus, .header:nth-last-child(2):hover\n")
-// .append(" { background-color: #999999; }\n")
-// .append(".section { position: absolute; top: 42px; min-width: 100%;\n")
-// .append(" padding-top: 18px; border-top: 1px solid #dddddd; }\n")
-// .append(".section > * { margin-left: 18px; }\n")
-// .append(":target + .section, .section:last-child { display: block; }\n")
-// .append(".section, :target + .section ~ .section { display: none; }\n")
-// .append("h1 { font-size: 18px; font-weight: normal; margin: 10px 0; }\n")
-// .append("h2 { font-size: 15px; }\n")
-// .append("h2:not(:first-child) { margin-top: 2em; }\n")
-// .append("table { border-collapse: collapse; border-spacing: 0;\n")
-// .append(" margin-top: 1.5em; }\n")
-// .append("table, thead { border-width: 1px 0; border-style: solid;\n")
-// .append(" border-color: #dddddd; text-align: left; }\n")
-// .append("th.name, td.name { padding: 1ex 2em 1ex 0; }\n")
-// .append("tbody > tr:hover { background-color: #cccccc; }\n")
-// .append(".code { font-family: \"Courier New\", monospace; }\n")
-// .append(".code, .tree li { line-height: 15px; }\n")
-// .append(".code a { text-decoration: underline; color: #666666; }\n")
-// .append(".xml .ns { font-style: italic; color: #999999; }\n")
-// .append("ul, .tree { list-style-type: none; }\n")
-// .append("div > ul.expr, div > .expand, .tree { padding-left: 0; }\n")
-// .append(".expr, .expand, .null, .numeric { padding-left: 1.5em; }\n")
-// .append("</style>\n")
-// .append("</head>\n")
-// .append("<body>\n");
-// char count = '0';
-// for (final DebugInfo part : parts) {
-// writer.append("<div class=\"header\" id=\"sec").append(++count).append("\">\n")
-// .append("<h1><a href=\"#sec").append(count).append("\">")
-// .append(part.getName())
-// .append("</a></h1>\n")
-// .append("</div>\n")
-// .append("<div class=\"section\">\n");
-// part.appendHtml(writer);
-// writer.append("</div>\n");
-// }
-// writer.append("</body>\n")
-// .append("</html>\n")
-// .close();
+
+ writer.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\n")
+ .append(" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n")
+ .append("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n")
+ .append("<head>\n")
+ .append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n")
+ .append("<title>")
+ .append(escapeHtml(title))
+ .append("</title>\n")
+ .append("<style type=\"text/css\">\n")
+ .append("body { font-family: Arial, sans-serif; font-size: 13px;\n")
+ .append(" line-height: 16px; margin: 0;\n")
+ .append(" background-color: #eeeeee; color: #333333; }\n")
+ .append(".header { float: left; }\n")
+ .append(".header a { line-height: 22px; padding: 10px 18px;\n")
+ .append(" text-decoration: none; color: #333333; }\n")
+ .append(":target, .header:nth-last-child(2) { background-color: #cccccc; }\n")
+ .append(":target ~ .header:nth-last-child(2) { background-color: inherit; }\n")
+ .append(".header:focus, .header:hover,\n")
+ .append(" .header:nth-last-child(2):focus, .header:nth-last-child(2):hover\n")
+ .append(" { background-color: #999999; }\n")
+ .append(".section { position: absolute; top: 42px; min-width: 100%;\n")
+ .append(" padding-top: 18px; border-top: 1px solid #dddddd; }\n")
+ .append(".section > * { margin-left: 18px; }\n")
+ .append(":target + .section, .section:last-child { display: block; }\n")
+ .append(".section, :target + .section ~ .section { display: none; }\n")
+ .append("h1 { font-size: 18px; font-weight: normal; margin: 10px 0; }\n")
+ .append("h2 { font-size: 15px; }\n")
+ .append("h2:not(:first-child) { margin-top: 2em; }\n")
+ .append("table { border-collapse: collapse; border-spacing: 0;\n")
+ .append(" margin-top: 1.5em; }\n")
+ .append("table, thead { border-width: 1px 0; border-style: solid;\n")
+ .append(" border-color: #dddddd; text-align: left; }\n")
+ .append("th.name, td.name { padding: 1ex 2em 1ex 0; }\n")
+ .append("tbody > tr:hover { background-color: #cccccc; }\n")
+ .append(".code { font-family: \"Courier New\", monospace; }\n")
+ .append(".code, .tree li { line-height: 15px; }\n")
+ .append(".code a { text-decoration: underline; color: #666666; }\n")
+ .append(".xml .ns { font-style: italic; color: #999999; }\n")
+ .append("ul, .tree { list-style-type: none; }\n")
+ .append("div > ul.expr, div > .expand, .tree { padding-left: 0; }\n")
+ .append(".expr, .expand, .null, .numeric { padding-left: 1.5em; }\n")
+ .append("</style>\n")
+ .append("</head>\n")
+ .append("<body>\n");
+ char count = '0';
+ for (final DebugTab part : parts) {
+ writer.append("<div class=\"header\" id=\"sec").append(++count).append("\">\n")
+ .append("<h1><a href=\"#sec").append(count).append("\">")
+ .append(part.getName())
+ .append("</a></h1>\n")
+ .append("</div>\n")
+ .append("<div class=\"section\">\n");
+ part.appendHtml(writer);
+ writer.append("</div>\n");
+ }
+ writer.append("</body>\n")
+ .append("</html>\n")
+ .close();
byte[] bytes = writer.toString().getBytes("UTF-8");
return new ByteArrayInputStream(bytes);
}
@@ -262,21 +251,21 @@ public class DebugResponseHelperImpl implements DebugResponseHelper {
}
gen.writeEndObject();
}
-//
-// protected static void appendHtmlTable(final Writer writer, final Map<String, String> entries) throws IOException {
-// writer.append("<table>\n<thead>\n")
-// .append("<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n")
-// .append("</thead>\n<tbody>\n");
-// for (final String name : entries.keySet()) {
-// final String value = entries.get(name);
-// if (value != null) {
-// writer.append("<tr><td class=\"name\">").append(name).append("</td>")
-// .append("<td class=\"value\">")
-// .append(ODataDebugResponseWrapper.escapeHtml(value))
-// .append("</td></tr>\n");
-// }
-// }
-// writer.append("</tbody>\n</table>\n");
-// }
+
+ protected static void appendHtmlTable(final Writer writer, final Map<String, String> entries) throws IOException {
+ writer.append("<table>\n<thead>\n")
+ .append("<tr><th class=\"name\">Name</th><th class=\"value\">Value</th></tr>\n")
+ .append("</thead>\n<tbody>\n");
+ for (final String name : entries.keySet()) {
+ final String value = entries.get(name);
+ if (value != null) {
+ writer.append("<tr><td class=\"name\">").append(name).append("</td>")
+ .append("<td class=\"value\">")
+ .append(escapeHtml(value))
+ .append("</td></tr>\n");
+ }
+ }
+ writer.append("</tbody>\n</table>\n");
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3dae763f/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTab.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTab.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTab.java
new file mode 100644
index 0000000..8847e33
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/debug/DebugTab.java
@@ -0,0 +1,50 @@
+/*
+ * 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.server.core.debug;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+
+
+/**
+ * Debug information.
+ */
+public interface DebugTab {
+
+ /**
+ * Gets the name of this debug information part, useful as title.
+ * @return the name
+ */
+ public String getName();
+
+ /**
+ * Appends the content of this debug information part
+ * to the given JSON stream writer.
+ * @param jsonGenerator a JSON generator
+ */
+ public void appendJson(JsonGenerator jsonGenerator) throws IOException;
+
+ /**
+ * Appends the content of this debug information part to the given writer.
+ * @param writer a {@link Writer}
+ */
+ public void appendHtml(Writer writer) throws IOException;
+}
[10/18] olingo-odata4 git commit: [OLINGO-713] Minor change system
query options - expand
Posted by ch...@apache.org.
[OLINGO-713] Minor change system query options - expand
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/b146a403
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/b146a403
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/b146a403
Branch: refs/heads/OLINGO-640
Commit: b146a403bb4e8333d2152c9b5667bd0ab063ed02
Parents: b477bde
Author: Michael Bolz <mi...@sap.com>
Authored: Mon Jul 27 10:21:14 2015 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Mon Jul 27 10:21:14 2015 +0200
----------------------------------------------------------------------
.../java/myservice/mynamespace/service/DemoEdmProvider.java | 6 +++---
samples/tutorials/p6_queryoptions-es/src/main/webapp/index.jsp | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b146a403/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
----------------------------------------------------------------------
diff --git a/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java b/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
index 7b1fef8..248cfba 100755
--- a/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
+++ b/samples/tutorials/p6_queryoptions-es/src/main/java/myservice/mynamespace/service/DemoEdmProvider.java
@@ -77,7 +77,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
// navigation property: many-to-one, null not allowed (product must have a category)
CsdlNavigationProperty navProp = new CsdlNavigationProperty().setName("Category")
- .setType(ET_CATEGORY_FQN).setNullable(false).setPartner("Products");
+ .setType(ET_CATEGORY_FQN).setNullable(false).setPartner("RelProducts");
List<CsdlNavigationProperty> navPropList = new ArrayList<CsdlNavigationProperty>();
navPropList.add(navProp);
@@ -100,7 +100,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
propertyRef.setName("ID");
// navigation property: one-to-many
- CsdlNavigationProperty navProp = new CsdlNavigationProperty().setName("Products")
+ CsdlNavigationProperty navProp = new CsdlNavigationProperty().setName("RelProducts")
.setType(ET_PRODUCT_FQN).setCollection(true).setPartner("Category");
List<CsdlNavigationProperty> navPropList = new ArrayList<CsdlNavigationProperty>();
navPropList.add(navProp);
@@ -147,7 +147,7 @@ public class DemoEdmProvider extends CsdlAbstractEdmProvider {
// navigation
CsdlNavigationPropertyBinding navPropBinding = new CsdlNavigationPropertyBinding();
navPropBinding.setTarget("Products"); // the target entity set, where the navigation property points to
- navPropBinding.setPath("Products"); // the path from entity type to navigation property
+ navPropBinding.setPath("RelProducts"); // the path from entity type to navigation property
List<CsdlNavigationPropertyBinding> navPropBindingList = new ArrayList<CsdlNavigationPropertyBinding>();
navPropBindingList.add(navPropBinding);
entitySet.setNavigationPropertyBindings(navPropBindingList);
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b146a403/samples/tutorials/p6_queryoptions-es/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/samples/tutorials/p6_queryoptions-es/src/main/webapp/index.jsp b/samples/tutorials/p6_queryoptions-es/src/main/webapp/index.jsp
index cee3a31..344b026 100755
--- a/samples/tutorials/p6_queryoptions-es/src/main/webapp/index.jsp
+++ b/samples/tutorials/p6_queryoptions-es/src/main/webapp/index.jsp
@@ -31,10 +31,10 @@ under the License.
<a href="DemoService.svc/Products/?$expand=Category">Expand - /Products/?$expand=Category</a>
</li>
<li>
- <a href="DemoService.svc/Categories(1)/?$expand=Products">Expand - /Categories(1)/?$expand=Products</a>
+ <a href="DemoService.svc/Categories(1)/?$expand=RelProducts">Expand - /Categories(1)/?$expand=RelProducts</a>
</li>
<li>
- <a href="DemoService.svc/Categories/?$expand=Products">Expand - /DemoService.svc/Categories/?$expand=Products</a>
+ <a href="DemoService.svc/Categories/?$expand=RelProducts">Expand - /Categories/?$expand=RelProducts</a>
</li>
</ul>
[18/18] olingo-odata4 git commit: [OLINGO-640] Minor adjustments to
tests and deleted logger
Posted by ch...@apache.org.
[OLINGO-640] Minor adjustments to tests and deleted logger
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/db0b9d39
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/db0b9d39
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/db0b9d39
Branch: refs/heads/OLINGO-640
Commit: db0b9d39de3a708320e5141bf4c9fed3b9c0e68a
Parents: 3665970
Author: Christian Amend <ch...@sap.com>
Authored: Tue Aug 4 16:23:42 2015 +0200
Committer: Christian Amend <ch...@sap.com>
Committed: Tue Aug 4 16:23:42 2015 +0200
----------------------------------------------------------------------
.../fit/tecsvc/client/NavigationITCase.java | 8 +-
.../core/serializer/xml/ODataXmlSerializer.java | 247 +-
.../serializer/xml/ODataXmlSerializerTest.java | 2434 +++++++++---------
3 files changed, 1386 insertions(+), 1303 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/db0b9d39/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/NavigationITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/NavigationITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/NavigationITCase.java
index a153f06..efcb168 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/NavigationITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/NavigationITCase.java
@@ -38,7 +38,7 @@ import org.apache.olingo.fit.util.StringHelper;
import org.junit.Assert;
import org.junit.Test;
-public final class NavigationITCase extends AbstractBaseTestITCase {
+public class NavigationITCase extends AbstractBaseTestITCase {
private final ODataClient client = getClient();
@@ -60,7 +60,7 @@ public final class NavigationITCase extends AbstractBaseTestITCase {
appendKeySegment(32767).build()).rawExecute();
String zeroLevelResponseBody = StringHelper.asString(zeroLevelResponse);
- assertTrue(zeroLevelResponseBody.contains("\"@odata.context\":\"$metadata#ESAllPrim/$entity\""));
+ assertTrue(zeroLevelResponseBody.contains("\"$metadata#ESAllPrim/$entity\""));
// one navigation
final InputStream oneLevelResponse = client.getRetrieveRequestFactory().getEntityRequest(
@@ -70,7 +70,7 @@ public final class NavigationITCase extends AbstractBaseTestITCase {
.rawExecute();
String oneLevelResponseBody = StringHelper.asString(oneLevelResponse);
- assertTrue(oneLevelResponseBody.contains("\"@odata.context\":\"../$metadata#ESTwoPrim/$entity\""));
+ assertTrue(oneLevelResponseBody.contains("\"../$metadata#ESTwoPrim/$entity\""));
// two navigation
final InputStream twoLevelResponse = client.getRetrieveRequestFactory().getEntityRequest(
@@ -81,7 +81,7 @@ public final class NavigationITCase extends AbstractBaseTestITCase {
.rawExecute();
String twoLevelResponseBody = StringHelper.asString(twoLevelResponse);
- assertTrue(twoLevelResponseBody.contains("\"@odata.context\":\"../../$metadata#ESTwoPrim/$entity\""));
+ assertTrue(twoLevelResponseBody.contains("\"../../$metadata#ESTwoPrim/$entity\""));
}
@Test
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/db0b9d39/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
index de50032..b9413f7 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
@@ -6,9 +6,9 @@
* 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
@@ -67,8 +67,6 @@ import org.apache.olingo.server.core.serializer.SerializerResultImpl;
import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
import org.apache.olingo.server.core.serializer.utils.ContextURLBuilder;
import org.apache.olingo.server.core.serializer.utils.ExpandSelectHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
public class ODataXmlSerializer implements ODataSerializer {
private static final String DATA = "d";
@@ -81,18 +79,16 @@ public class ODataXmlSerializer implements ODataSerializer {
private static final String NS_METADATA = "http://docs.oasis-open.org/odata/ns/metadata";
private static final String NS_DATA = "http://docs.oasis-open.org/odata/ns/data";
private static final String NS_SCHEMA = "http://docs.oasis-open.org/odata/ns/scheme";
-
- private static final Logger log = LoggerFactory.getLogger(ODataXmlSerializer.class);
@Override
public SerializerResult serviceDocument(final ServiceMetadata metadata, final String serviceRoot)
throws SerializerException {
CircleStreamBuffer buffer;
XMLStreamWriter xmlStreamWriter = null;
-
+ SerializerException cachedException = null;
try {
buffer = new CircleStreamBuffer();
- xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(buffer.getOutputStream(),
+ xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(buffer.getOutputStream(),
DEFAULT_CHARSET);
ServiceDocumentXmlSerializer serializer = new ServiceDocumentXmlSerializer(metadata, serviceRoot);
serializer.writeServiceDocument(xmlStreamWriter);
@@ -101,16 +97,20 @@ public class ODataXmlSerializer implements ODataSerializer {
return SerializerResultImpl.with().content(buffer.getInputStream()).build();
} catch (final XMLStreamException e) {
- log.error(e.getMessage(), e);
- throw new SerializerException("An I/O exception occurred.", e,
- SerializerException.MessageKeys.IO_EXCEPTION);
+ cachedException =
+ new SerializerException("An I/O exception occurred.", e, SerializerException.MessageKeys.IO_EXCEPTION);
+ throw cachedException;
} finally {
if (xmlStreamWriter != null) {
try {
xmlStreamWriter.close();
} catch (XMLStreamException e) {
- throw new SerializerException("An I/O exception occurred.", e,
- SerializerException.MessageKeys.IO_EXCEPTION);
+ if (cachedException != null) {
+ throw cachedException;
+ } else {
+ throw new SerializerException("An I/O exception occurred.", e,
+ SerializerException.MessageKeys.IO_EXCEPTION);
+ }
}
}
}
@@ -120,10 +120,10 @@ public class ODataXmlSerializer implements ODataSerializer {
public SerializerResult metadataDocument(final ServiceMetadata serviceMetadata) throws SerializerException {
CircleStreamBuffer buffer;
XMLStreamWriter xmlStreamWriter = null;
-
+ SerializerException cachedException = null;
try {
buffer = new CircleStreamBuffer();
- xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(buffer.getOutputStream(),
+ xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(buffer.getOutputStream(),
DEFAULT_CHARSET);
MetadataDocumentXmlSerializer serializer = new MetadataDocumentXmlSerializer(serviceMetadata);
serializer.writeMetadataDocument(xmlStreamWriter);
@@ -132,16 +132,20 @@ public class ODataXmlSerializer implements ODataSerializer {
return SerializerResultImpl.with().content(buffer.getInputStream()).build();
} catch (final XMLStreamException e) {
- log.error(e.getMessage(), e);
- throw new SerializerException("An I/O exception occurred.", e,
- SerializerException.MessageKeys.IO_EXCEPTION);
+ cachedException =
+ new SerializerException("An I/O exception occurred.", e, SerializerException.MessageKeys.IO_EXCEPTION);
+ throw cachedException;
} finally {
if (xmlStreamWriter != null) {
try {
xmlStreamWriter.close();
} catch (XMLStreamException e) {
- throw new SerializerException("An I/O exception occurred.", e,
- SerializerException.MessageKeys.IO_EXCEPTION);
+ if (cachedException != null) {
+ throw cachedException;
+ } else {
+ throw new SerializerException("An I/O exception occurred.", e,
+ SerializerException.MessageKeys.IO_EXCEPTION);
+ }
}
}
}
@@ -151,31 +155,31 @@ public class ODataXmlSerializer implements ODataSerializer {
public SerializerResult error(final ODataServerError error) throws SerializerException {
CircleStreamBuffer buffer;
XMLStreamWriter writer = null;
-
+
if (error == null) {
throw new SerializerException("ODataError object MUST NOT be null!",
SerializerException.MessageKeys.NULL_INPUT);
}
-
+
try {
buffer = new CircleStreamBuffer();
- writer = XMLOutputFactory.newInstance().createXMLStreamWriter(buffer.getOutputStream(),
+ writer = XMLOutputFactory.newInstance().createXMLStreamWriter(buffer.getOutputStream(),
DEFAULT_CHARSET);
writer.writeStartDocument(ODataSerializer.DEFAULT_CHARSET, "1.0");
-
+
writer.writeStartElement("error");
writer.writeDefaultNamespace(NS_METADATA);
writeErrorDetails(String.valueOf(error.getStatusCode()), error.getMessage(), error.getTarget(), writer);
if (error.getDetails() != null && !error.getDetails().isEmpty()) {
writer.writeStartElement("details");
- for (ODataErrorDetail inner:error.getDetails()) {
+ for (ODataErrorDetail inner : error.getDetails()) {
writeErrorDetails(inner.getCode(), inner.getMessage(), inner.getTarget(), writer);
}
writer.writeEndElement();
}
- writer.writeEndElement();
+ writer.writeEndElement();
writer.writeEndDocument();
-
+
writer.flush();
writer.close();
return SerializerResultImpl.with().content(buffer.getInputStream()).build();
@@ -192,7 +196,7 @@ public class ODataXmlSerializer implements ODataSerializer {
writer.writeCharacters(String.valueOf(code));
writer.writeEndElement();
}
-
+
writer.writeStartElement("message");
writer.writeCharacters(message);
writer.writeEndElement();
@@ -200,22 +204,22 @@ public class ODataXmlSerializer implements ODataSerializer {
if (target != null) {
writer.writeStartElement("target");
writer.writeCharacters(target);
- writer.writeEndElement();
+ writer.writeEndElement();
}
}
-
+
@Override
public SerializerResult entityCollection(final ServiceMetadata metadata,
final EdmEntityType entityType, final EntityCollection entitySet,
final EntityCollectionSerializerOptions options) throws SerializerException {
-
+
final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
if (options.onlyReferences()) {
ReferenceCollectionSerializerOptions rso = ReferenceCollectionSerializerOptions.with()
.contextURL(contextURL).build();
return entityReferenceCollection(metadata, entityType, entitySet, rso);
}
-
+
CircleStreamBuffer buffer;
XMLStreamWriter writer = null;
try {
@@ -226,11 +230,11 @@ public class ODataXmlSerializer implements ODataSerializer {
writer.writeNamespace(ATOM, NS_ATOM);
writer.writeNamespace(METADATA, NS_METADATA);
writer.writeNamespace(DATA, NS_DATA);
-
- writer.writeAttribute(METADATA, NS_METADATA, "context",
+
+ writer.writeAttribute(METADATA, NS_METADATA, "context",
ContextURLBuilder.create(contextURL).toASCIIString());
writeMetadataETag(metadata, writer);
-
+
writer.writeStartElement(ATOM, "id", NS_ATOM);
writer.writeCharacters(options.getId());
writer.writeEndElement();
@@ -242,7 +246,7 @@ public class ODataXmlSerializer implements ODataSerializer {
if (entitySet.getNext() != null) {
writeNextLink(entitySet, writer);
}
-
+
writeEntitySet(metadata, entityType, entitySet,
options.getExpand(), options.getSelect(), options.onlyReferences(), writer);
@@ -261,13 +265,13 @@ public class ODataXmlSerializer implements ODataSerializer {
public SerializerResult entity(final ServiceMetadata metadata, final EdmEntityType entityType,
final Entity entity, final EntitySerializerOptions options) throws SerializerException {
final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
-
+
if (options.onlyReferences()) {
ReferenceSerializerOptions rso = ReferenceSerializerOptions.with()
.contextURL(contextURL).build();
return entityReference(metadata, entityType, entity, rso);
}
-
+
CircleStreamBuffer buffer;
XMLStreamWriter writer = null;
try {
@@ -295,12 +299,12 @@ public class ODataXmlSerializer implements ODataSerializer {
return contextURL;
}
- private void writeMetadataETag(final ServiceMetadata metadata, XMLStreamWriter writer)
+ private void writeMetadataETag(final ServiceMetadata metadata, XMLStreamWriter writer)
throws XMLStreamException {
if (metadata != null
&& metadata.getServiceMetadataETagSupport() != null
&& metadata.getServiceMetadataETagSupport().getMetadataETag() != null) {
- writer.writeAttribute(METADATA, NS_METADATA, "metadata-etag",
+ writer.writeAttribute(METADATA, NS_METADATA, "metadata-etag",
metadata.getServiceMetadataETagSupport().getMetadataETag());
}
}
@@ -316,7 +320,7 @@ public class ODataXmlSerializer implements ODataSerializer {
protected void writeEntity(final ServiceMetadata metadata, final EdmEntityType entityType,
final Entity entity, final ContextURL contextURL, final ExpandOption expand,
- final SelectOption select, final boolean onlyReference, final XMLStreamWriter writer,
+ final SelectOption select, final boolean onlyReference, final XMLStreamWriter writer,
final boolean top) throws XMLStreamException, SerializerException {
writer.writeStartElement(ATOM, "entry", NS_ATOM);
@@ -324,24 +328,24 @@ public class ODataXmlSerializer implements ODataSerializer {
writer.writeNamespace(ATOM, NS_ATOM);
writer.writeNamespace(METADATA, NS_METADATA);
writer.writeNamespace(DATA, NS_DATA);
-
+
if (contextURL != null) { // top-level entity
- writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
+ writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
ContextURLBuilder.create(contextURL).toASCIIString());
writeMetadataETag(metadata, writer);
-
+
}
}
if (entity.getETag() != null) {
writer.writeAttribute(METADATA, NS_METADATA, "etag", entity.getETag());
}
-
+
writer.writeStartElement(NS_ATOM, "id");
writer.writeCharacters(entity.getId().toASCIIString());
writer.writeEndElement();
writerAuthorInfo(entity.getTitle(), writer);
-
+
writer.writeStartElement(NS_ATOM, "link");
writer.writeAttribute("rel", "edit");
writer.writeAttribute("href", entity.getId().toASCIIString());
@@ -355,41 +359,41 @@ public class ODataXmlSerializer implements ODataSerializer {
} else {
String id = entity.getId().toASCIIString();
if (id.endsWith("/")) {
- writer.writeAttribute("src", id+"$value");
+ writer.writeAttribute("src", id + "$value");
} else {
- writer.writeAttribute("src", id+"/$value");
+ writer.writeAttribute("src", id + "/$value");
}
}
writer.writeEndElement();
}
-
+
// write media links
- for (Link link:entity.getMediaEditLinks()) {
+ for (Link link : entity.getMediaEditLinks()) {
writeLink(writer, link);
}
EdmEntityType resolvedType = resolveEntityType(metadata, entityType, entity.getType());
writeNavigationProperties(metadata, resolvedType, entity, expand, writer);
-
+
writer.writeStartElement(ATOM, "category", NS_ATOM);
writer.writeAttribute("scheme", NS_SCHEMA);
- writer.writeAttribute("term", "#"+resolvedType.getFullQualifiedName().getFullQualifiedNameAsString());
+ writer.writeAttribute("term", "#" + resolvedType.getFullQualifiedName().getFullQualifiedNameAsString());
writer.writeEndElement();
-
+
// In the case media, content is sibiling
if (!entityType.hasStream()) {
writer.writeStartElement(NS_ATOM, "content");
writer.writeAttribute("type", "application/xml");
}
-
+
writer.writeStartElement(METADATA, "properties", NS_METADATA);
writeProperties(metadata, resolvedType, entity.getProperties(), select, writer);
writer.writeEndElement(); // properties
-
+
if (!entityType.hasStream()) { // content
writer.writeEndElement();
}
- writer.writeEndElement(); //entry
+ writer.writeEndElement(); // entry
}
private void writerAuthorInfo(final String title, final XMLStreamWriter writer) throws XMLStreamException {
@@ -400,12 +404,12 @@ public class ODataXmlSerializer implements ODataSerializer {
writer.writeEndElement();
writer.writeStartElement(NS_ATOM, "summary");
writer.writeEndElement();
-
+
writer.writeStartElement(NS_ATOM, "updated");
writer.writeCharacters(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
- .format(new Date(System.currentTimeMillis())));
+ .format(new Date(System.currentTimeMillis())));
writer.writeEndElement();
-
+
writer.writeStartElement(NS_ATOM, "author");
writer.writeStartElement(NS_ATOM, "name");
writer.writeEndElement();
@@ -460,9 +464,9 @@ public class ODataXmlSerializer implements ODataSerializer {
.getFullQualifiedName().getFullQualifiedNameAsString());
}
- protected void writeProperties(final ServiceMetadata metadata, final EdmStructuredType type,
- final List<Property> properties, final SelectOption select, final XMLStreamWriter writer)
- throws XMLStreamException, SerializerException {
+ protected void writeProperties(final ServiceMetadata metadata, final EdmStructuredType type,
+ final List<Property> properties, final SelectOption select, final XMLStreamWriter writer)
+ throws XMLStreamException, SerializerException {
final boolean all = ExpandSelectHelper.isAll(select);
final Set<String> selected = all ? null :
ExpandSelectHelper.getSelectedPropertyNames(select.getSelectItems());
@@ -486,7 +490,7 @@ public class ODataXmlSerializer implements ODataSerializer {
ExpandSelectHelper.getExpandedPropertyNames(expand.getExpandItems());
for (final String propertyName : type.getNavigationPropertyNames()) {
final EdmNavigationProperty property = type.getNavigationProperty(propertyName);
- final Link navigationLink = getOrCreateLink(linked, propertyName);
+ final Link navigationLink = getOrCreateLink(linked, propertyName);
if (expandAll || expanded.contains(propertyName)) {
final ExpandItem innerOptions = expandAll ? null :
ExpandSelectHelper.getExpandItem(expand.getExpandItems(), propertyName);
@@ -495,14 +499,14 @@ public class ODataXmlSerializer implements ODataSerializer {
SerializerException.MessageKeys.NOT_IMPLEMENTED);
}
if (navigationLink != null) {
- writeLink(writer, navigationLink, false);
+ writeLink(writer, navigationLink, false);
writer.writeStartElement(METADATA, "inline", NS_METADATA);
writeExpandedNavigationProperty(metadata, property, navigationLink,
innerOptions == null ? null : innerOptions.getExpandOption(),
- innerOptions == null ? null : innerOptions.getSelectOption(),
- innerOptions == null ? false: innerOptions.isRef(),
+ innerOptions == null ? null : innerOptions.getSelectOption(),
+ innerOptions == null ? false : innerOptions.isRef(),
writer);
- writer.writeEndElement();
+ writer.writeEndElement();
writer.writeEndElement();
}
} else {
@@ -512,33 +516,34 @@ public class ODataXmlSerializer implements ODataSerializer {
} else {
for (final String propertyName : type.getNavigationPropertyNames()) {
writeLink(writer, getOrCreateLink(linked, propertyName));
- }
+ }
}
- for (Link link:linked.getAssociationLinks()) {
+ for (Link link : linked.getAssociationLinks()) {
writeLink(writer, link);
- }
+ }
}
-
- protected Link getOrCreateLink(final Linked linked, final String navigationPropertyName)
+
+ protected Link getOrCreateLink(final Linked linked, final String navigationPropertyName)
throws XMLStreamException {
Link link = linked.getNavigationLink(navigationPropertyName);
if (link == null) {
link = new Link();
- link.setRel("http://docs.oasis-open.org/odata/ns/related/"+navigationPropertyName);
+ link.setRel("http://docs.oasis-open.org/odata/ns/related/" + navigationPropertyName);
link.setType(Constants.ENTITY_SET_NAVIGATION_LINK_TYPE);
link.setTitle(navigationPropertyName);
EntityCollection target = new EntityCollection();
link.setInlineEntitySet(target);
- link.setHref(linked.getId().toASCIIString()+"/"+navigationPropertyName);
+ link.setHref(linked.getId().toASCIIString() + "/" + navigationPropertyName);
}
return link;
- }
-
+ }
+
private void writeLink(final XMLStreamWriter writer, final Link link) throws XMLStreamException {
writeLink(writer, link, true);
}
+
private void writeLink(final XMLStreamWriter writer, final Link link, final boolean close)
- throws XMLStreamException {
+ throws XMLStreamException {
writer.writeStartElement(ATOM, "link", NS_ATOM);
writer.writeAttribute("rel", link.getRel());
if (link.getType() != null) {
@@ -550,12 +555,12 @@ public class ODataXmlSerializer implements ODataSerializer {
writer.writeAttribute("href", link.getHref());
if (close) {
writer.writeEndElement();
- }
- }
+ }
+ }
protected void writeExpandedNavigationProperty(final ServiceMetadata metadata,
final EdmNavigationProperty property, final Link navigationLink,
- final ExpandOption innerExpand, final SelectOption innerSelect, boolean onlyReference,
+ final ExpandOption innerExpand, final SelectOption innerSelect, boolean onlyReference,
final XMLStreamWriter writer)
throws XMLStreamException, SerializerException {
if (property.isCollection()) {
@@ -577,7 +582,7 @@ public class ODataXmlSerializer implements ODataSerializer {
}
}
- protected void writeProperty(final ServiceMetadata metadata, final EdmProperty edmProperty,
+ protected void writeProperty(final ServiceMetadata metadata, final EdmProperty edmProperty,
final Property property,
final Set<List<String>> selectedPaths, final XMLStreamWriter writer) throws XMLStreamException,
SerializerException {
@@ -594,25 +599,25 @@ public class ODataXmlSerializer implements ODataSerializer {
}
writer.writeEndElement();
}
-
+
private String collectionType(EdmType type) {
- return "#Collection("+type.getFullQualifiedName().getFullQualifiedNameAsString()+")";
+ return "#Collection(" + type.getFullQualifiedName().getFullQualifiedNameAsString() + ")";
}
-
- private String complexType(ServiceMetadata metadata, EdmComplexType baseType, String definedType)
+
+ private String complexType(ServiceMetadata metadata, EdmComplexType baseType, String definedType)
throws SerializerException {
EdmComplexType type = resolveComplexType(metadata, baseType, definedType);
return type.getFullQualifiedName().getFullQualifiedNameAsString();
}
-
- private String derivedComplexType(ServiceMetadata metadata, EdmComplexType baseType, String definedType)
+
+ private String derivedComplexType(ServiceMetadata metadata, EdmComplexType baseType, String definedType)
throws SerializerException {
String derived = baseType.getFullQualifiedName().getFullQualifiedNameAsString();
if (derived.equals(definedType)) {
return null;
}
return definedType;
- }
+ }
private void writePropertyValue(final ServiceMetadata metadata, final EdmProperty edmProperty,
final Property property, final Set<List<String>> selectedPaths,
@@ -620,7 +625,7 @@ public class ODataXmlSerializer implements ODataSerializer {
try {
if (edmProperty.isPrimitive()) {
if (edmProperty.isCollection()) {
- writer.writeAttribute(METADATA, NS_METADATA, "type", "#Collection("+edmProperty.getType().getName()+")");
+ writer.writeAttribute(METADATA, NS_METADATA, "type", "#Collection(" + edmProperty.getType().getName() + ")");
writePrimitiveCollection((EdmPrimitiveType) edmProperty.getType(), property,
edmProperty.isNullable(), edmProperty.getMaxLength(),
edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(),
@@ -635,8 +640,8 @@ public class ODataXmlSerializer implements ODataSerializer {
writer.writeAttribute(METADATA, NS_METADATA, "type", collectionType(edmProperty.getType()));
writeComplexCollection(metadata, (EdmComplexType) edmProperty.getType(), property, selectedPaths, writer);
} else if (property.isComplex()) {
- writer.writeAttribute(METADATA, NS_METADATA, "type",
- "#"+complexType(metadata, (EdmComplexType) edmProperty.getType(), property.getType()));
+ writer.writeAttribute(METADATA, NS_METADATA, "type",
+ "#" + complexType(metadata, (EdmComplexType) edmProperty.getType(), property.getType()));
writeComplexValue(metadata, (EdmComplexType) edmProperty.getType(), property.asComplex().getValue(),
selectedPaths, writer);
} else if (property.isEnum()) {
@@ -677,7 +682,7 @@ public class ODataXmlSerializer implements ODataSerializer {
}
}
- private void writeComplexCollection(final ServiceMetadata metadata, final EdmComplexType type,
+ private void writeComplexCollection(final ServiceMetadata metadata, final EdmComplexType type,
final Property property, final Set<List<String>> selectedPaths, final XMLStreamWriter writer)
throws XMLStreamException, EdmPrimitiveTypeException, SerializerException {
for (Object value : property.asCollection()) {
@@ -711,7 +716,7 @@ public class ODataXmlSerializer implements ODataSerializer {
throw new SerializerException("Property type not yet supported!",
SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, property.getName());
} else if (property.isEnum()) {
- writer.writeAttribute(METADATA, NS_METADATA, "type", "#"+type.getName());
+ writer.writeAttribute(METADATA, NS_METADATA, "type", "#" + type.getName());
writePrimitiveValue(type, property.asEnum(),
isNullable, maxLength, precision, scale, isUnicode, writer);
} else {
@@ -728,8 +733,8 @@ public class ODataXmlSerializer implements ODataSerializer {
isNullable, maxLength, precision, scale, isUnicode);
if (value == null) {
writer.writeAttribute(DATA, NS_DATA, "null", "true");
- } else if(type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean)) {
- writer.writeCharacters(value);
+ } else if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean)) {
+ writer.writeCharacters(value);
} else if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Byte)
|| type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Decimal)
|| type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Double)
@@ -744,7 +749,7 @@ public class ODataXmlSerializer implements ODataSerializer {
}
}
- protected void writeComplexValue(final ServiceMetadata metadata, final EdmComplexType type,
+ protected void writeComplexValue(final ServiceMetadata metadata, final EdmComplexType type,
final List<Property> properties, final Set<List<String>> selectedPaths, final XMLStreamWriter writer)
throws XMLStreamException, EdmPrimitiveTypeException, SerializerException {
for (final String propertyName : type.getPropertyNames()) {
@@ -781,11 +786,11 @@ public class ODataXmlSerializer implements ODataSerializer {
writer.writeStartElement(METADATA, "value", NS_METADATA);
writer.writeNamespace(METADATA, NS_METADATA);
if (contextURL != null) {
- writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
+ writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
ContextURLBuilder.create(contextURL).toASCIIString());
}
writeMetadataETag(metadata, writer);
- if(property.isNull()) {
+ if (property.isNull()) {
writer.writeAttribute(METADATA, NS_METADATA, "null", "true");
} else {
writePrimitive(type, property,
@@ -797,7 +802,7 @@ public class ODataXmlSerializer implements ODataSerializer {
writer.writeEndDocument();
writer.flush();
writer.close();
-
+
return SerializerResultImpl.with().content(buffer.getInputStream()).build();
} catch (final XMLStreamException e) {
throw new SerializerException("An I/O exception occurred.", e,
@@ -816,7 +821,7 @@ public class ODataXmlSerializer implements ODataSerializer {
property.getName(), property.getValue().toString());
}
}
- }
+ }
}
@Override
@@ -835,7 +840,7 @@ public class ODataXmlSerializer implements ODataSerializer {
writer.writeNamespace(DATA, NS_DATA);
writer.writeAttribute(METADATA, NS_METADATA, "type", "#"
+ resolvedType.getFullQualifiedName().getFullQualifiedNameAsString());
- writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
+ writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
ContextURLBuilder.create(contextURL).toASCIIString());
writeMetadataETag(metadata, writer);
if (property.isNull()) {
@@ -869,11 +874,11 @@ public class ODataXmlSerializer implements ODataSerializer {
writer.writeStartElement(METADATA, "value", NS_METADATA);
writer.writeNamespace(METADATA, NS_METADATA);
if (contextURL != null) {
- writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
+ writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
ContextURLBuilder.create(contextURL).toASCIIString());
- }
+ }
writeMetadataETag(metadata, writer);
- writer.writeAttribute(METADATA, NS_METADATA, "type", "#Collection("+type.getName()+")");
+ writer.writeAttribute(METADATA, NS_METADATA, "type", "#Collection(" + type.getName() + ")");
writePrimitiveCollection(type, property,
options.isNullable(), options.getMaxLength(), options.getPrecision(), options.getScale(),
options.isUnicode(),
@@ -882,7 +887,7 @@ public class ODataXmlSerializer implements ODataSerializer {
writer.writeEndDocument();
writer.flush();
writer.close();
-
+
return SerializerResultImpl.with().content(buffer.getInputStream()).build();
} catch (final XMLStreamException e) {
throw new SerializerException("An I/O exception occurred.", e,
@@ -901,7 +906,7 @@ public class ODataXmlSerializer implements ODataSerializer {
property.getName(), property.getValue().toString());
}
}
- }
+ }
}
@Override
@@ -918,8 +923,8 @@ public class ODataXmlSerializer implements ODataSerializer {
writer.writeStartElement(METADATA, "value", NS_METADATA);
writer.writeNamespace(METADATA, NS_METADATA);
writer.writeNamespace(DATA, NS_DATA);
- writer.writeAttribute(METADATA, NS_METADATA, "type", collectionType(type));
- writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
+ writer.writeAttribute(METADATA, NS_METADATA, "type", collectionType(type));
+ writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
ContextURLBuilder.create(contextURL).toASCIIString());
writeMetadataETag(metadata, writer);
writeComplexCollection(metadata, type, property, null, writer);
@@ -939,11 +944,11 @@ public class ODataXmlSerializer implements ODataSerializer {
}
@Override
- public SerializerResult reference(final ServiceMetadata metadata, final EdmEntitySet edmEntitySet,
+ public SerializerResult reference(final ServiceMetadata metadata, final EdmEntitySet edmEntitySet,
final Entity entity, final ReferenceSerializerOptions options) throws SerializerException {
return entityReference(metadata, edmEntitySet.getEntityType(), entity, options);
}
-
+
protected SerializerResult entityReference(final ServiceMetadata metadata, final EdmEntityType entityType,
final Entity entity, ReferenceSerializerOptions options) throws SerializerException {
CircleStreamBuffer buffer;
@@ -962,14 +967,14 @@ public class ODataXmlSerializer implements ODataSerializer {
SerializerException.MessageKeys.IO_EXCEPTION);
}
}
-
- private void writeReference(ServiceMetadata metadata, EdmEntityType entityType,
+
+ private void writeReference(ServiceMetadata metadata, EdmEntityType entityType,
Entity entity, ContextURL contextURL, XMLStreamWriter writer, boolean top) throws XMLStreamException {
writer.writeStartElement(METADATA, "ref", NS_METADATA);
if (top) {
writer.writeNamespace(METADATA, NS_METADATA);
if (contextURL != null) { // top-level entity
- writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
+ writer.writeAttribute(METADATA, NS_METADATA, CONTEXT,
ContextURLBuilder.create(contextURL).toASCIIString());
}
}
@@ -978,12 +983,12 @@ public class ODataXmlSerializer implements ODataSerializer {
}
@Override
- public SerializerResult referenceCollection(final ServiceMetadata metadata, final EdmEntitySet edmEntitySet,
- final EntityCollection entityCollection, ReferenceCollectionSerializerOptions options)
- throws SerializerException {
+ public SerializerResult referenceCollection(final ServiceMetadata metadata, final EdmEntitySet edmEntitySet,
+ final EntityCollection entityCollection, ReferenceCollectionSerializerOptions options)
+ throws SerializerException {
return entityReferenceCollection(metadata, edmEntitySet.getEntityType(), entityCollection, options);
}
-
+
protected SerializerResult entityReferenceCollection(final ServiceMetadata metadata,
final EdmEntityType entityType, final EntityCollection entitySet,
ReferenceCollectionSerializerOptions options) throws SerializerException {
@@ -1019,16 +1024,16 @@ public class ODataXmlSerializer implements ODataSerializer {
throw new SerializerException("An I/O exception occurred.", e,
SerializerException.MessageKeys.IO_EXCEPTION);
}
- }
-
- private void writeCount(final EntityCollection entitySet, XMLStreamWriter writer)
+ }
+
+ private void writeCount(final EntityCollection entitySet, XMLStreamWriter writer)
throws XMLStreamException {
writer.writeStartElement(METADATA, "count", NS_METADATA);
writer.writeCharacters(String.valueOf(entitySet.getCount()));
writer.writeEndElement();
}
- private void writeNextLink(final EntityCollection entitySet, XMLStreamWriter writer)
+ private void writeNextLink(final EntityCollection entitySet, XMLStreamWriter writer)
throws XMLStreamException {
writer.writeStartElement(ATOM, "link", NS_ATOM);
writer.writeAttribute("rel", "next");