You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2014/07/08 13:54:17 UTC
[1/2] git commit: [OLINGO-317] Integration into tecsvc
Repository: olingo-odata4
Updated Branches:
refs/heads/master b3cfc3510 -> 45b7289f8
[OLINGO-317] Integration into 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/3ca91891
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/3ca91891
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/3ca91891
Branch: refs/heads/master
Commit: 3ca91891bd1986c918a9c5418c0ae0b09d80687f
Parents: d860717
Author: Michael Bolz <mi...@sap.com>
Authored: Tue Jul 8 09:18:01 2014 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Tue Jul 8 09:18:14 2014 +0200
----------------------------------------------------------------------
.../core/serializer/json/JsonDataProvider.java | 46 +++
.../json/ODataJsonSerializerTest.java | 28 +-
.../olingo/server/tecsvc/TechnicalServlet.java | 27 +-
.../olingo/server/tecsvc/data/DataProvider.java | 25 +-
.../server/tecsvc/data/JefDataProvider.java | 349 +++++++++++++++++++
.../tecsvc/processor/SampleJsonProcessor.java | 229 ------------
.../tecsvc/processor/TechnicalProcessor.java | 132 ++++++-
.../tecsvc/provider/PropertyProvider.java | 3 +
.../src/main/resources/ESAllPrim.json | 56 +++
.../src/main/resources/ESCollAllPrim.json | 59 ++++
.../src/main/resources/ESCompAllPrim.json | 65 ++++
.../src/main/resources/ESMixPrimCollComp.json | 68 ++++
.../src/main/resources/ESTwoPrim.json | 1 +
.../tecsvc/data/JsonDataProviderTest.java | 186 ++++++++++
.../olingo/server/tecsvc/data/StringHelper.java | 206 +++++++++++
15 files changed, 1202 insertions(+), 278 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ca91891/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/json/JsonDataProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/json/JsonDataProvider.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/json/JsonDataProvider.java
new file mode 100644
index 0000000..0a4cf73
--- /dev/null
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/json/JsonDataProvider.java
@@ -0,0 +1,46 @@
+/*
+ * 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.serializer.json;
+
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntitySet;
+import org.apache.olingo.commons.api.data.ResWrap;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.apache.olingo.commons.api.serialization.ODataDeserializerException;
+import org.apache.olingo.commons.core.serialization.JsonDeserializer;
+import org.junit.Test;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+
+/**
+ */
+public class JsonDataProvider {
+ @Test
+ public void testMe() throws Exception {
+ FileInputStream fis = new FileInputStream("/tmp/ESAllPrim.json");
+ ResWrap<EntitySet> wrapper = new JsonDeserializer(ODataServiceVersion.V40, true).toEntitySet(fis);
+ EntitySet es = wrapper.getPayload();
+ for (Entity entity : es.getEntities()) {
+ System.out.println(entity);
+ }
+
+ ODataJsonSerializer serializer = new ODataJsonSerializer();
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ca91891/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
index ec2619b..91e49b9 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
@@ -337,8 +337,8 @@ public class ODataJsonSerializerTest {
"\"PropertyDecimal\":4711.1174," +
"\"PropertyBinary\":\"BAcBAQ==\"," +
"\"PropertyDate\":\"2014-03-19\"," +
- "\"PropertyDateTimeOffset\":\"2014-03-19T10:12:00Z\"," +
- "\"PropertyDuration\":\"P16148425DT0S\"," +
+ "\"PropertyDateTimeOffset\":\"2014-03-19T10:12:00+01:00\"," +
+ "\"PropertyDuration\":\"P16148383DT8H0S\"," +
"\"PropertyGuid\":\"0000aaaa-00bb-00cc-00dd-000000ffffff\"," +
"\"PropertyTimeOfDay\":\"10:12:00\"" +
"}";
@@ -396,8 +396,8 @@ public class ODataJsonSerializerTest {
"\"CollPropertyDecimal\":[4711.1174,1174.4711]," +
"\"CollPropertyBinary\":[\"BAcBAQ==\",\"dGVzdA==\"]," +
"\"CollPropertyDate\":[\"2014-03-19\",\"2014-07-02\"]," +
- "\"CollPropertyDateTimeOffset\":[\"2014-03-19T10:12:00Z\",\"2014-07-02T13:30:00Z\"]," +
- "\"CollPropertyDuration\":[\"P16148425DT0S\",\"P16253562DT12H0S\"]," +
+ "\"CollPropertyDateTimeOffset\":[\"2014-03-19T10:12:00+01:00\",\"2014-07-02T13:30:00+02:00\"]," +
+ "\"CollPropertyDuration\":[\"P16148383DT8H0S\",\"P16253479DT4H0S\"]," +
"\"CollPropertyGuid\":[\"0000aaaa-00bb-00cc-00dd-000000ffffff\",\"0000ffff-00dd-00cc-00bb-000000aaaaaa\"]," +
"\"CollPropertyTimeOfDay\":[\"10:12:00\",\"13:30:00\"]" +
"}";
@@ -433,8 +433,8 @@ public class ODataJsonSerializerTest {
"\"PropertyDecimal\":4711.1174," +
"\"PropertyBinary\":\"BAcBAQ==\"," +
"\"PropertyDate\":\"2014-03-19\"," +
- "\"PropertyDateTimeOffset\":\"2014-03-19T10:12:00Z\"," +
- "\"PropertyDuration\":\"P16148425DT0S\"," +
+ "\"PropertyDateTimeOffset\":\"2014-03-19T10:12:00+01:00\"," +
+ "\"PropertyDuration\":\"P16148383DT8H0S\"," +
"\"PropertyGuid\":\"0000aaaa-00bb-00cc-00dd-000000ffffff\"," +
"\"PropertyTimeOfDay\":\"10:12:00\"" +
"}}";
@@ -455,10 +455,10 @@ public class ODataJsonSerializerTest {
private Entity createETCollAllPrim(int id) {
Entity entity = new EntityImpl();
- Calendar date = createCalendarInstance();
+ Calendar date = Calendar.getInstance();
date.set(2014, Calendar.MARCH, 19, 10, 12, 0);
date.set(Calendar.MILLISECOND, 0);
- Calendar date2 = createCalendarInstance();
+ Calendar date2 = Calendar.getInstance();
date2.set(2014, Calendar.JULY, 2, 13, 30, 0);
date2.set(Calendar.MILLISECOND, 0);
//
@@ -489,7 +489,7 @@ public class ODataJsonSerializerTest {
entity.addProperty(createProperty("Collection(Edm.Date)", TecSvcSimpleProperty.Collection_Date,
ValueType.COLLECTION_PRIMITIVE, date, date2));
entity.addProperty(createProperty("Collection(Edm.DateTimeOffset)", TecSvcSimpleProperty.Collection_DateTimeOffset,
- ValueType.COLLECTION_PRIMITIVE, date, date2));
+ ValueType.COLLECTION_PRIMITIVE, date.getTime(), date2.getTime()));
entity.addProperty(createProperty("Collection(Edm.Duration)", TecSvcSimpleProperty.Collection_Duration,
ValueType.COLLECTION_PRIMITIVE, date.getTimeInMillis(), date2.getTimeInMillis()));
entity.addProperty(createProperty("Collection(Edm.Guid)", TecSvcSimpleProperty.Collection_Guid,
@@ -503,7 +503,7 @@ public class ODataJsonSerializerTest {
private Entity createETAllPrim(int id) {
Entity entity = new EntityImpl();
- Calendar date = createCalendarInstance();
+ Calendar date = Calendar.getInstance();
date.set(2014, Calendar.MARCH, 19, 10, 12, 0);
date.set(Calendar.MILLISECOND, 0);
entity.addProperty(createProperty("Edm.Int16", TecSvcSimpleProperty.Int16, ValueType.PRIMITIVE, id));
@@ -522,7 +522,7 @@ public class ODataJsonSerializerTest {
new byte[]{0x04, 0x07, 0x01, 0x01}));
entity.addProperty(createProperty("Edm.Date", TecSvcSimpleProperty.Date, ValueType.PRIMITIVE, date));
entity.addProperty(createProperty("Edm.DateTimeOffset", TecSvcSimpleProperty.DateTimeOffset, ValueType.PRIMITIVE,
- date));
+ date.getTime()));
entity.addProperty(createProperty("Edm.Duration", TecSvcSimpleProperty.Duration, ValueType.PRIMITIVE,
date.getTimeInMillis()));
entity.addProperty(createProperty("Edm.Guid", TecSvcSimpleProperty.Guid, ValueType.PRIMITIVE,
@@ -531,12 +531,6 @@ public class ODataJsonSerializerTest {
return entity;
}
- private Calendar createCalendarInstance() {
- Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.ENGLISH);
- cal.set(Calendar.ZONE_OFFSET, 0);
- return cal;
- }
-
private String streamToString(InputStream result) throws IOException {
byte[] buffer = new byte[8192];
StringBuilder sb = new StringBuilder();
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ca91891/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 5d4e463..ddddca8 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
@@ -18,22 +18,22 @@
*/
package org.apache.olingo.server.tecsvc;
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataHttpHandler;
import org.apache.olingo.server.tecsvc.data.DataProvider;
-import org.apache.olingo.server.tecsvc.processor.SampleJsonProcessor;
+import org.apache.olingo.server.tecsvc.data.JefDataProvider;
+import org.apache.olingo.server.tecsvc.processor.TechnicalProcessor;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
public class TechnicalServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@@ -45,19 +45,18 @@ public class TechnicalServlet extends HttpServlet {
protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException,
IOException {
try {
+ OData odata = OData.newInstance();
+ Edm edm = odata.createEdm(new EdmTechProvider());
+
if (dataProvider == null) {
- dataProvider = new DataProvider();
+ dataProvider = new JefDataProvider(edm);
}
-
dataProvider.reset();
- OData odata = OData.newInstance();
- Edm edm = odata.createEdm(new EdmTechProvider());
ODataHttpHandler handler = odata.createHandler(edm);
-// handler.register(new TechnicalProcessor(dataProvider));
- handler.register(new SampleJsonProcessor());
+ handler.register(new TechnicalProcessor(dataProvider));
handler.process(req, resp);
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ca91891/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
index 2281ac7..820ae3a 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.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
@@ -18,11 +18,24 @@
*/
package org.apache.olingo.server.tecsvc.data;
-public class DataProvider {
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntitySet;
- public void reset() {
- // TODO Auto-generated method stub
- }
+public interface DataProvider {
+ void reset() throws DataProviderException;
+
+ EntitySet readAll(String entitySetName) throws DataProviderException;
+
+ Entity read(String entitySetName, Object ... keys) throws DataProviderException;
+ static class DataProviderException extends Exception {
+ public DataProviderException(String message, Throwable throwable) {
+ super(message, throwable);
+ }
+
+ public DataProviderException(String message) {
+ super(message);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ca91891/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/JefDataProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/JefDataProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/JefDataProvider.java
new file mode 100644
index 0000000..18f4cb7
--- /dev/null
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/JefDataProvider.java
@@ -0,0 +1,349 @@
+/*
+ * 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.tecsvc.data;
+
+import org.apache.olingo.commons.api.data.*;
+import org.apache.olingo.commons.api.edm.*;
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.apache.olingo.commons.api.serialization.ODataDeserializerException;
+import org.apache.olingo.commons.core.data.EntityImpl;
+import org.apache.olingo.commons.core.data.EntitySetImpl;
+import org.apache.olingo.commons.core.data.LinkedComplexValueImpl;
+import org.apache.olingo.commons.core.data.PropertyImpl;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
+import org.apache.olingo.commons.core.serialization.JsonDeserializer;
+import org.apache.olingo.server.tecsvc.provider.ContainerProvider;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ */
+public class JefDataProvider implements DataProvider {
+
+ private final Edm edm;
+ private final Map<String, EntitySetContainer> esName2esContainer = new HashMap<String, EntitySetContainer>();
+
+ public JefDataProvider(Edm edm) {
+ this.edm = edm;
+ }
+
+ @Override
+ public void reset() throws DataProviderException {
+ initialize("ESAllPrim");
+ initialize("ESCompAllPrim");
+ initialize("ESCollAllPrim");
+ initialize("ESCollAllPrim");
+ }
+
+ @Override
+ public Entity read(String entitySetName, Object ... keys) throws DataProviderException {
+ EntitySetContainer container = esName2esContainer.get(entitySetName);
+ if(container == null) {
+ container = initialize(entitySetName);
+ }
+ return container.getEntity(keys);
+ }
+
+ @Override
+ public EntitySet readAll(String entitySetName) throws DataProviderException {
+ try {
+ EdmEntitySet edmEntitySet = edm.getEntityContainer(ContainerProvider.nameContainer).getEntitySet(entitySetName);
+ return createEntitySetContainer(edmEntitySet).getEntitySet();
+ } catch (ODataDeserializerException e) {
+ throw new DataProviderException("Failure during reset/createEntitySetContainer", e);
+ }
+ }
+
+ private EntitySetContainer initialize(String entitySetName) throws DataProviderException {
+ try {
+ EdmEntityContainer edmEntityContainer = edm.getEntityContainer(ContainerProvider.nameContainer);
+ EntitySetContainer entitySetContainer = createEntitySetContainer(edmEntityContainer.getEntitySet(entitySetName));
+ esName2esContainer.put(entitySetContainer.getEntitySetName(), entitySetContainer);
+ return entitySetContainer;
+ } catch (ODataDeserializerException e) {
+ throw new DataProviderException("Failure during reset/createEntitySetContainer", e);
+ }
+ }
+
+ private EntitySetContainer createEntitySetContainer(EdmEntitySet edmEntitySet)
+ throws ODataDeserializerException, DataProviderException {
+ String name = edmEntitySet.getName();
+ InputStream fis = Thread.currentThread().getContextClassLoader().getResourceAsStream(name + ".json");
+ if(fis == null) {
+ throw new DataProviderException("Failure during createEntitySetContainer, unable to load entity set [" +
+ name + "] from file.");
+ }
+
+ ResWrap<EntitySet> wrapper = new JsonDeserializer(ODataServiceVersion.V40, true).toEntitySet(fis);
+ EntitySet es = wrapper.getPayload();
+
+ EntitySetContainer container = new EntitySetContainer(edmEntitySet);
+ for (Entity entity : es.getEntities()) {
+ Entity norm = normalize(entity, edmEntitySet.getEntityType());
+ container.addEntity(norm);
+ }
+
+ return container;
+ }
+
+ private Entity normalize(Entity entity, EdmEntityType entityType) throws DataProviderException {
+ EntityImpl ei = new EntityImpl();
+
+ List<Property> propertyList = entity.getProperties();
+
+ try {
+ List<Property> normalized = normalizeProperties(propertyList, entityType);
+ ei.getProperties().addAll(normalized);
+ return ei;
+ } catch (Exception e) {
+ throw new DataProviderException("Failure during normalization of entity properties (for entity -> '" +
+ entity + "')", e);
+ }
+ }
+
+ private List<Property> normalizeProperties(Collection<Property> propertyList, EdmStructuredType entityType)
+ throws IllegalAccessException, DataProviderException, EdmPrimitiveTypeException {
+ List<Property> normalized = new ArrayList<Property>();
+
+ for (Property prop: propertyList) {
+ EdmElement element = entityType.getProperty(prop.getName());
+ // FIXME
+ if(element == null && prop.getName().contains("PropertyComp")) {
+ String fixedName = prop.getName().replace("PropertyComp", "PropertyComplex");
+ element = entityType.getProperty(fixedName);
+ }
+ //
+ Property result = normalizeProperty(prop, element);
+ normalized.add(result);
+ }
+
+ return normalized;
+ }
+
+ private Property normalizeProperty(Property prop, EdmElement element)
+ throws EdmPrimitiveTypeException, IllegalAccessException, DataProviderException {
+ return normalizeValue(prop.getValue(), element);
+ }
+
+ private Property normalizeValue(Object value, EdmElement element)
+ throws EdmPrimitiveTypeException, IllegalAccessException, DataProviderException {
+ if(element instanceof EdmProperty) {
+ EdmProperty property = (EdmProperty) element;
+ if(property.isPrimitive()) {
+ return PropBuilder.build(property).value(value);
+ } else {
+ // recursion
+ if(property.isCollection()) {
+ return normalizeComplexCollection((Collection<?>) value, property);
+ }
+
+ return normalizeComplexValue(value, property);
+ }
+ }
+ throw new DataProviderException("Unable to convert value [" + value + "] for property [" + element + "].");
+ }
+
+ private Property normalizeComplexCollection(Collection<?> values, EdmProperty property)
+ throws IllegalAccessException, DataProviderException, EdmPrimitiveTypeException {
+
+ List<Object> norm = new ArrayList<Object>();
+ boolean linkedComplex = false;
+ for (Object value : values) {
+ if(value instanceof Collection) {
+ Property r = normalizeComplexValue(value, property);
+ norm.add(r.getValue());
+ } else if(value instanceof LinkedComplexValue) {
+ LinkedComplexValue lcv = (LinkedComplexValue) value;
+ Property r = normalizeComplexValue(lcv, property);
+ linkedComplex = r.isLinkedComplex();
+ norm.add(r.getValue());
+ }
+ }
+
+ if(linkedComplex) {
+ return PropBuilder.build(property).linkedComplexCollection(norm);
+ }
+ return PropBuilder.build(property).complexCollection(norm);
+ }
+
+ private Property normalizeComplexValue(Object value, EdmProperty property)
+ throws IllegalAccessException, DataProviderException, EdmPrimitiveTypeException {
+ EdmComplexType complex = edm.getComplexType(property.getType().getFullQualifiedName());
+ if(value instanceof Collection) {
+ Collection<Property> norm = normalizeProperties((Collection<Property>) value, complex);
+ return PropBuilder.build(property).complex(norm);
+ } else if(value instanceof LinkedComplexValue) {
+ LinkedComplexValue lcv = (LinkedComplexValue) value;
+ Collection<Property> norm = normalizeProperties(lcv.getValue(), complex);
+ LinkedComplexValueImpl no = new LinkedComplexValueImpl();
+ no.getValue().addAll(norm);
+ return PropBuilder.build(property).linkedComplex(no);
+ }
+ throw new DataProviderException("Unable to convert value [" + value + "] for property [" + property + "].");
+ }
+
+ private static class EntitySetContainer {
+ final EdmEntitySet entitySet;
+ final Map<String, Entity> key2Entity;
+
+ public EntitySetContainer(EdmEntitySet entitySet) {
+ this.entitySet = entitySet;
+ key2Entity = new HashMap<String, Entity>();
+ }
+
+ public void addEntity(Entity entity) {
+ String key = createKey(entity, entitySet);
+ key2Entity.put(key, entity);
+ }
+
+ public EntitySet getEntitySet() {
+ EntitySetImpl resultEntitySet = new EntitySetImpl();
+ resultEntitySet.getEntities().addAll(key2Entity.values());
+ return resultEntitySet;
+ }
+
+ public String getEntitySetName() {
+ return entitySet.getName();
+ }
+
+ public Entity getEntity(Object ... keyValues) {
+ List<String> keyProperties = new ArrayList<String>();
+ Collections.sort(keyProperties);
+ for (Object keyValue : keyValues) {
+ keyProperties.add(String.valueOf(keyValue));
+ }
+ String key = keyProperties.toString();
+ return key2Entity.get(key);
+ }
+
+ private static String createKey(Entity entity, EdmEntitySet entitySet) {
+ List<String> keyPropertyValues = new ArrayList<String>();
+ List<EdmKeyPropertyRef> keyRefs = entitySet.getEntityType().getKeyPropertyRefs();
+ for (EdmKeyPropertyRef keyRef : keyRefs) {
+ Property keyProperty = entity.getProperty(keyRef.getKeyPropertyName());
+ keyPropertyValues.add(String.valueOf(keyProperty.getValue()));
+ }
+ Collections.sort(keyPropertyValues);
+ return keyPropertyValues.toString();
+ }
+ }
+
+
+ private static class PropBuilder {
+ final PropertyImpl property;
+ final EdmProperty edmProperty;
+
+ private PropBuilder(EdmProperty edmProperty) {
+ this.edmProperty = edmProperty;
+ property = new PropertyImpl(edmProperty.getType().getFullQualifiedName().getFullQualifiedNameAsString(),
+ edmProperty.getName());
+ }
+
+ public static PropBuilder build(EdmProperty edmProperty) {
+ return new PropBuilder(edmProperty);
+ }
+
+ public PropertyImpl primitive(Object ... value) {
+ if(edmProperty.isCollection()) {
+ property.setValue(ValueType.COLLECTION_PRIMITIVE, Arrays.asList(value));
+ } else {
+ if(value == null || value.length == 0) {
+ property.setValue(ValueType.PRIMITIVE, null);
+ } else {
+ property.setValue(ValueType.PRIMITIVE, value[0]);
+ }
+ }
+ return property;
+ }
+
+ public PropertyImpl complexCollection(Object value) {
+ if(edmProperty.isCollection()) {
+ property.setValue(ValueType.COLLECTION_COMPLEX, value);
+ } else {
+ throw new IllegalArgumentException("Property is no collection.");
+ }
+ return property;
+ }
+
+ public PropertyImpl complex(Object value) {
+ property.setValue(ValueType.COMPLEX, value);
+ return property;
+ }
+
+ public PropertyImpl linkedComplexCollection(Object value) {
+ if(edmProperty.isCollection()) {
+ property.setValue(ValueType.COLLECTION_LINKED_COMPLEX, value);
+ } else {
+ throw new IllegalArgumentException("Property is no collection.");
+ }
+ return property;
+ }
+
+ public PropertyImpl linkedComplex(Object value) {
+ property.setValue(ValueType.LINKED_COMPLEX, value);
+ return property;
+ }
+
+ public Property value(Object value) throws EdmPrimitiveTypeException {
+ FullQualifiedName fqn = edmProperty.getType().getFullQualifiedName();
+
+ try {
+ EdmPrimitiveTypeKind kind = EdmPrimitiveTypeKind.valueOfFQN(ODataServiceVersion.V40, fqn);
+ EdmPrimitiveType instance = EdmPrimitiveTypeFactory.getInstance(kind);
+
+ if(edmProperty.isCollection()) {
+ final Collection<?> values;
+ if(value.getClass().isArray()) {
+ values = Arrays.asList(value);
+ } else if(value instanceof Collection) {
+ values = (Collection<?>) value;
+ } else {
+ throw new EdmPrimitiveTypeException("Invalid collection value object class: " + value.getClass());
+ }
+ Collection<Object> result = new ArrayList<Object>(values.size());
+ for (Object v : values) {
+ String valueStr = String.valueOf(v);
+ result.add(instance.valueOfString(valueStr,
+ edmProperty.isNullable(), edmProperty.getMaxLength(),
+ edmProperty.getPrecision(), edmProperty.getScale(),
+ true, instance.getDefaultType()));
+ }
+ property.setValue(ValueType.COLLECTION_PRIMITIVE, result);
+ } else {
+ String valueStr = String.valueOf(value);
+ Object result = instance.valueOfString(valueStr,
+ edmProperty.isNullable(), edmProperty.getMaxLength(),
+ edmProperty.getPrecision(), edmProperty.getScale(),
+ true, instance.getDefaultType());
+ property.setValue(ValueType.PRIMITIVE, result);
+ }
+ } catch (IllegalArgumentException e) {
+ complex(value);
+ }
+ return property;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ca91891/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/SampleJsonProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/SampleJsonProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/SampleJsonProcessor.java
deleted file mode 100644
index e34fd42..0000000
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/SampleJsonProcessor.java
+++ /dev/null
@@ -1,229 +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.tecsvc.processor;
-
-import java.net.URI;
-import java.util.*;
-
-import org.apache.olingo.commons.api.data.ContextURL;
-import org.apache.olingo.commons.api.data.Entity;
-import org.apache.olingo.commons.api.data.EntitySet;
-import org.apache.olingo.commons.api.data.Property;
-import org.apache.olingo.commons.api.data.ValueType;
-import org.apache.olingo.commons.api.edm.Edm;
-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.commons.api.format.ContentType;
-import org.apache.olingo.commons.api.format.ODataFormat;
-import org.apache.olingo.commons.api.http.HttpStatusCode;
-import org.apache.olingo.commons.core.data.EntityImpl;
-import org.apache.olingo.commons.core.data.EntitySetImpl;
-import org.apache.olingo.commons.core.data.PropertyImpl;
-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.processor.CollectionProcessor;
-import org.apache.olingo.server.api.processor.EntityProcessor;
-import org.apache.olingo.server.api.serializer.ODataSerializer;
-import org.apache.olingo.server.api.uri.UriInfo;
-import org.apache.olingo.server.api.uri.UriResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SampleJsonProcessor implements CollectionProcessor, EntityProcessor {
- private static final Logger LOG = LoggerFactory.getLogger(SampleJsonProcessor.class);
-
- private OData odata;
- private Edm edm;
-
- @Override
- public void init(OData odata, Edm edm) {
- this.odata = odata;
- this.edm = edm;
- }
-
- @Override
- public void readCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
- long time = System.nanoTime();
-
- LOG.info((System.nanoTime() - time) / 1000 + " microseconds");
- time = System.nanoTime();
- ODataSerializer serializer = odata.createSerializer(ODataFormat.JSON);
- EdmEntitySet edmEntitySet = getEntitySet(uriInfo);
- ContextURL contextUrl = getContextUrl(request, edmEntitySet.getEntityType());
- EntitySet entitySet = createEntitySet(edmEntitySet.getEntityType(), contextUrl.getURI().toASCIIString());
- response.setContent(serializer.entitySet(edmEntitySet, entitySet, contextUrl));
- LOG.info("Finished in " + (System.nanoTime() - time) / 1000 + " microseconds");
-
- response.setStatusCode(HttpStatusCode.OK.getStatusCode());
- response.setHeader("Content-Type", ContentType.APPLICATION_JSON.toContentTypeString());
- }
-
- @Override
- public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
- long time = System.nanoTime();
-
- LOG.info((System.nanoTime() - time) / 1000 + " microseconds");
- time = System.nanoTime();
- ODataSerializer serializer = odata.createSerializer(ODataFormat.JSON);
- EdmEntityType entityType = getEntityType(uriInfo);
- Entity entity = createEntity(entityType);
-
- response.setContent(serializer.entity(entityType, entity,
- getContextUrl(request, entityType)));
- LOG.info("Finished in " + (System.nanoTime() - time) / 1000 + " microseconds");
-
- response.setStatusCode(HttpStatusCode.OK.getStatusCode());
- response.setHeader("Content-Type", ContentType.APPLICATION_JSON.toContentTypeString());
- }
-
- private ContextURL getContextUrl(ODataRequest request, EdmEntityType entityType) {
- return ContextURL.getInstance(URI.create(request.getRawBaseUri() + "/" + entityType.getName()));
- }
-
- public EdmEntityType getEntityType(UriInfo uriInfo) {
- return getEntitySet(uriInfo).getEntityType();
- }
-
- public EdmEntitySet getEntitySet(UriInfo uriInfo) {
- List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
- if(resourcePaths.isEmpty()) {
- throw new RuntimeException("Invalid resource path.");
- }
- String entitySetName = resourcePaths.get(resourcePaths.size()-1).toString();
- return edm.getEntityContainer(new FullQualifiedName("com.sap.odata.test1", "Container"))
- .getEntitySet(entitySetName);
- }
-
- protected Entity createEntity(EdmEntityType entityType) {
- boolean complex = (entityType.getName().contains("Comp"));
- if(entityType.getName().contains("Coll")) {
- return createEntityWithCollection(complex);
- }
- return createEntity(complex);
- }
-
- protected Entity createEntity(boolean complex) {
- Entity entity = new EntityImpl();
- Property property = new PropertyImpl();
- property.setName("PropertyString");
- property.setValue(ValueType.PRIMITIVE, "dummyValue");
- entity.getProperties().add(property);
- Property propertyInt = new PropertyImpl();
- propertyInt.setName("PropertyInt16");
- propertyInt.setValue(ValueType.PRIMITIVE, 42);
- entity.getProperties().add(propertyInt);
- Property propertyGuid = new PropertyImpl();
- propertyGuid.setName("PropertyGuid");
- propertyGuid.setValue(ValueType.PRIMITIVE, UUID.randomUUID());
- entity.getProperties().add(propertyGuid);
-
- if(complex) {
- entity.addProperty(createComplexProperty());
- }
-
- return entity;
- }
-
- protected Entity createEntityWithCollection(boolean complex) {
- Entity entity = new EntityImpl();
- Property propertyInt = new PropertyImpl();
- propertyInt.setName("PropertyInt16");
- propertyInt.setValue(ValueType.PRIMITIVE, 42);
- Property property = new PropertyImpl();
- property.setName("CollPropertyString");
- property.setValue(ValueType.COLLECTION_PRIMITIVE, Arrays.asList("dummyValue", "dummyValue_2"));
- entity.getProperties().add(property);
- entity.getProperties().add(propertyInt);
- Property propertyGuid = new PropertyImpl();
- propertyGuid.setName("CollPropertyGuid");
- propertyGuid.setValue(ValueType.COLLECTION_PRIMITIVE, Arrays.asList(UUID.randomUUID(), UUID.randomUUID()));
- entity.getProperties().add(propertyGuid);
-
- if(complex) {
- entity.addProperty(createCollectionOfComplexProperty());
- }
-
- return entity;
- }
-
- protected Property createComplexProperty() {
- List<Property> properties = new ArrayList<Property>();
- Property property = new PropertyImpl();
- property.setName("PropertyString");
- property.setValue(ValueType.PRIMITIVE, "dummyValue");
- properties.add(property);
- Property propertyInt = new PropertyImpl();
- propertyInt.setName("PropertyInt16");
- propertyInt.setValue(ValueType.PRIMITIVE, 42);
- properties.add(propertyInt);
- Property propertyGuid = new PropertyImpl();
- propertyGuid.setName("PropertyGuid");
- propertyGuid.setValue(ValueType.PRIMITIVE, UUID.randomUUID());
- properties.add(propertyGuid);
-
- return new PropertyImpl("com.sap.odata.test1.ETCompAllPrim", "PropertyComplex", ValueType.COMPLEX,
- properties);
- }
-
- protected Property createCollectionOfComplexProperty() {
- List<Property> properties = new ArrayList<Property>();
- Property property = new PropertyImpl();
- property.setName("PropertyString");
- property.setValue(ValueType.PRIMITIVE, "dummyValue");
- properties.add(property);
- Property propertyInt = new PropertyImpl();
- propertyInt.setName("PropertyInt16");
- propertyInt.setValue(ValueType.PRIMITIVE, 42);
- properties.add(propertyInt);
- Property propertyGuid = new PropertyImpl();
- propertyGuid.setName("PropertyGuid");
- propertyGuid.setValue(ValueType.PRIMITIVE, UUID.randomUUID());
- properties.add(propertyGuid);
-
- List<Property> properties2 = new ArrayList<Property>();
- Property property2 = new PropertyImpl();
- property2.setName("PropertyString");
- property2.setValue(ValueType.PRIMITIVE, "dummyValue2");
- properties2.add(property2);
- Property property2Int = new PropertyImpl();
- property2Int.setName("PropertyInt16");
- property2Int.setValue(ValueType.PRIMITIVE, 44);
- properties2.add(property2Int);
- Property property2Guid = new PropertyImpl();
- property2Guid.setName("PropertyGuid");
- property2Guid.setValue(ValueType.PRIMITIVE, UUID.randomUUID());
- properties2.add(property2Guid);
-
- return new PropertyImpl("com.sap.odata.test1.ETCompAllPrim", "PropertyComplex", ValueType.COMPLEX,
- Arrays.asList(properties, properties2));
- }
-
- protected EntitySet createEntitySet(EdmEntityType edmEntityType, String baseUri) {
- EntitySet entitySet = new EntitySetImpl();
- int count = (int) ((Math.random() * 50) + 1);
- entitySet.setCount(count);
- entitySet.setNext(URI.create(baseUri + "nextLink"));
- for (int i = 0; i < count; i++) {
- entitySet.getEntities().add(createEntity(edmEntityType));
- }
- return entitySet;
- }
-}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ca91891/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
index b3c671c..0b2c6bd 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
@@ -18,35 +18,143 @@
*/
package org.apache.olingo.server.tecsvc.processor;
-import java.io.ByteArrayInputStream;
-
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.edm.Edm;
+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.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.processor.CollectionProcessor;
import org.apache.olingo.server.api.processor.EntityProcessor;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
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.UriResourceKind;
import org.apache.olingo.server.tecsvc.data.DataProvider;
+import org.apache.olingo.server.tecsvc.data.JefDataProvider;
+import org.apache.olingo.server.tecsvc.provider.ContainerProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
public class TechnicalProcessor implements CollectionProcessor, EntityProcessor {
- public TechnicalProcessor(final DataProvider dataProvider) {}
+
+ private static final Logger LOG = LoggerFactory.getLogger(TechnicalProcessor.class);
+
+ private OData odata;
+ private Edm edm;
+ private DataProvider dataProvider;
+
+ public TechnicalProcessor(final DataProvider dataProvider) {
+ this.dataProvider = dataProvider;
+ }
@Override
- public void init(final OData odata, final Edm edm) {}
+ public void init(OData odata, Edm edm) {
+ this.odata = odata;
+ this.edm = edm;
+ if(dataProvider == null) {
+ this.dataProvider = new JefDataProvider(edm);
+ }
+ }
@Override
- public void readEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
- final String format) {
- response.setContent(new ByteArrayInputStream("Entity".getBytes()));
- response.setStatusCode(200);
+ public void readCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
+ long time = System.nanoTime();
+
+ LOG.info((System.nanoTime() - time) / 1000 + " microseconds");
+ time = System.nanoTime();
+ ODataSerializer serializer = odata.createSerializer(ODataFormat.JSON);
+ EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo);
+ ContextURL contextUrl = getContextUrl(request, edmEntitySet.getEntityType());
+ try {
+ EntitySet entitySet = readEntitySetInternal(edmEntitySet, contextUrl);
+ if(entitySet == null) {
+ response.setStatusCode(HttpStatusCode.NOT_FOUND.getStatusCode());
+ } else {
+ response.setContent(serializer.entitySet(edmEntitySet, entitySet, contextUrl));
+ LOG.info("Finished in " + (System.nanoTime() - time) / 1000 + " microseconds");
+
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader("Content-Type", ContentType.APPLICATION_JSON.toContentTypeString());
+ }
+ } catch (DataProvider.DataProviderException e) {
+ response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
+ }
}
@Override
- public void readCollection(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
- final String format) {
- response.setContent(new ByteArrayInputStream("EntitySet".getBytes()));
- response.setStatusCode(200);
+ public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
+ long time = System.nanoTime();
+
+ LOG.info((System.nanoTime() - time) / 1000 + " microseconds");
+ time = System.nanoTime();
+ ODataSerializer serializer = odata.createSerializer(ODataFormat.JSON);
+ EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo);
+ try {
+ Entity entity = readEntityInternal(uriInfo, edmEntitySet);
+ if(entity == null) {
+ response.setStatusCode(HttpStatusCode.NOT_FOUND.getStatusCode());
+ } else {
+ response.setContent(serializer.entity(edmEntitySet.getEntityType(), entity,
+ getContextUrl(request, edmEntitySet.getEntityType())));
+ LOG.info("Finished in " + (System.nanoTime() - time) / 1000 + " microseconds");
+
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader("Content-Type", ContentType.APPLICATION_JSON.toContentTypeString());
+ }
+ } catch (DataProvider.DataProviderException e) {
+ response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
+ }
+ }
+
+ private Entity readEntityInternal(UriInfo uriInfo, EdmEntitySet entitySet)
+ throws DataProvider.DataProviderException {
+ List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+ if(!resourcePaths.isEmpty()) {
+ UriResource res = resourcePaths.get(resourcePaths.size()-1);
+ if(res.getKind() == UriResourceKind.entitySet) {
+ UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) res;
+ String key = resourceEntitySet.getKeyPredicates().get(0).getText();
+ return dataProvider.read(entitySet.getName(), key);
+ }
+ }
+ throw new RuntimeException("Invalid resource paths.. " + resourcePaths);
+ }
+
+ private ContextURL getContextUrl(ODataRequest request, EdmEntityType entityType) {
+ return ContextURL.getInstance(URI.create(request.getRawBaseUri() + "/" + entityType.getName()));
+ }
+
+ private EntitySet readEntitySetInternal(EdmEntitySet edmEntitySet, ContextURL contextUrl)
+ throws DataProvider.DataProviderException {
+ EntitySet entitySet = dataProvider.readAll(edmEntitySet.getName());
+ try {
+ entitySet.setNext(new URI(contextUrl.getServiceRoot().toASCIIString() + "/" +
+ edmEntitySet.getEntityType().getName()));
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Invalid uri syntax.", e);
+ }
+ return entitySet;
+ }
+
+ private EdmEntitySet getEdmEntitySet(UriInfo uriInfo) {
+ List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+ if(resourcePaths.isEmpty()) {
+ throw new RuntimeException("Invalid resource path.");
+ }
+ String entitySetName = resourcePaths.get(resourcePaths.size()-1).toString();
+ return edm.getEntityContainer(ContainerProvider.nameContainer).getEntitySet(entitySetName);
}
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ca91891/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java
index fe8c97c..491b6f3 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/PropertyProvider.java
@@ -284,6 +284,7 @@ public class PropertyProvider {
public static final Property propertyDateTimeOffset = new Property()
.setName("PropertyDateTimeOffset")
+ .setPrecision(20)
.setType(nameDateTimeOffset);
public static final Property propertyDateTimeOffset_NotNullable = new Property()
@@ -298,6 +299,7 @@ public class PropertyProvider {
public static final Property propertyDecimal = new Property()
.setName("PropertyDecimal")
+ .setScale(10)
.setType(nameDecimal);
public static final Property propertyDecimal_NotNullable = new Property()
@@ -438,6 +440,7 @@ public class PropertyProvider {
public static final Property propertyTimeOfDay = new Property()
.setName("PropertyTimeOfDay")
+ .setPrecision(10)
.setType(nameTimeOfDay);
public static final Property propertyTimeOfDay_NotNullable = new Property()
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ca91891/lib/server-tecsvc/src/main/resources/ESAllPrim.json
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/resources/ESAllPrim.json b/lib/server-tecsvc/src/main/resources/ESAllPrim.json
new file mode 100644
index 0000000..0e0da29
--- /dev/null
+++ b/lib/server-tecsvc/src/main/resources/ESAllPrim.json
@@ -0,0 +1,56 @@
+{"@odata.context": "$metadata#ESAllPrim", "value": [
+ {
+ "PropertyInt16": 32767,
+ "PropertyString": "First Resource - positive values",
+ "PropertyBoolean": true,
+ "PropertyByte": 255,
+ "PropertySByte": 127,
+ "PropertyInt32": 2147483647,
+ "PropertyInt64": 9223372036854775807,
+ "PropertySingle": 1.79000000E+20,
+ "PropertyDouble": -1.7900000000000000E+19,
+ "PropertyDecimal": 34,
+ "PropertyBinary": "ASNFZ4mrze8=",
+ "PropertyDate": "2012-12-03",
+ "PropertyDateTimeOffset": "2012-12-03T07:16:23Z",
+ "PropertyDuration": "P0DT0H0M6S",
+ "PropertyGuid": "01234567-89ab-cdef-0123-456789abcdef",
+ "PropertyTimeOfDay": "03:26:05"
+ },
+ {
+ "PropertyInt16": -32768,
+ "PropertyString": "Second Resource - negative values",
+ "PropertyBoolean": false,
+ "PropertyByte": 0,
+ "PropertySByte": -128,
+ "PropertyInt32": -2147483648,
+ "PropertyInt64": -9223372036854775808,
+ "PropertySingle": -1.79000000E+08,
+ "PropertyDouble": -1.7900000000000000E+05,
+ "PropertyDecimal": -34,
+ "PropertyBinary": "ASNFZ4mrze8=",
+ "PropertyDate": "2015-11-05",
+ "PropertyDateTimeOffset": "2005-12-03T07:17:08Z",
+ "PropertyDuration": "P0DT0H0M9S",
+ "PropertyGuid": "76543201-23ab-cdef-0123-456789dddfff",
+ "PropertyTimeOfDay": "23:49:14"
+ },
+ {
+ "PropertyInt16": 0,
+ "PropertyString": "",
+ "PropertyBoolean": false,
+ "PropertyByte": 0,
+ "PropertySByte": 0,
+ "PropertyInt32": 0,
+ "PropertyInt64": 0,
+ "PropertySingle": 0.00000000E+00,
+ "PropertyDouble": 0.0000000000000000E+00,
+ "PropertyDecimal": 0,
+ "PropertyBinary": "",
+ "PropertyDate": "1970-01-01",
+ "PropertyDateTimeOffset": "2005-12-03T00:00:00Z",
+ "PropertyDuration": "P0DT0H0M0S",
+ "PropertyGuid": "76543201-23ab-cdef-0123-456789cccddd",
+ "PropertyTimeOfDay": "00:01:01"
+ }
+]}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ca91891/lib/server-tecsvc/src/main/resources/ESCollAllPrim.json
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/resources/ESCollAllPrim.json b/lib/server-tecsvc/src/main/resources/ESCollAllPrim.json
new file mode 100644
index 0000000..89471d4
--- /dev/null
+++ b/lib/server-tecsvc/src/main/resources/ESCollAllPrim.json
@@ -0,0 +1,59 @@
+{"@odata.context": "$metadata#ESCollAllPrim", "value": [
+ {
+ "PropertyInt16": 1,
+ "CollPropertyString": ["spiderman@comic.com", "spidermaus@comic.com", "spidergirl@comic.com"],
+ "CollPropertyBoolean": [true, false, true],
+ "CollPropertyByte": [50, 200, 249],
+ "CollPropertySByte": [-120, 120, 126],
+ "CollPropertyInt16": [1000, 2000, 30112],
+ "CollPropertyInt32": [23232323, 11223355, 10000001],
+ "CollPropertyInt64": [929292929292, 333333333333, 444444444444],
+ "CollPropertySingle": [1.79000000E+03, 2.66000000E+04, 3.21000000E+03],
+ "CollPropertyDouble": [-1.7900000000000000E+04, -2.7800000000000000E+07, 3.2100000000000000E+03],
+ "CollPropertyDecimal": [12, -2, 1234],
+ "CollPropertyBinary": ["q83v", "ASNF", "VGeJ"],
+ "CollPropertyDate": ["1958-12-03", "1999-08-05", "2013-06-25"],
+ "CollPropertyDateTimeOffset": ["2015-08-12T03:08:34Z", "1970-03-28T12:11:10Z", "1948-02-17T09:09:09Z"],
+ "CollPropertyDuration": ["P0DT0H0M13S", "P0DT5H28M20S", "P0DT1H0M0S"],
+ "CollPropertyGuid": ["ffffff67-89ab-cdef-0123-456789aaaaaa", "eeeeee67-89ab-cdef-0123-456789bbbbbb", "cccccc67-89ab-cdef-0123-456789cccccc"],
+ "CollPropertyTimeOfDay": ["04:14:13", "23:59:59", "01:12:33"]
+ },
+ {
+ "PropertyInt16": 2,
+ "CollPropertyString": ["spiderman@comic.com", "spidermaus@comic.com", "spidergirl@comic.com"],
+ "CollPropertyBoolean": [true, false, true],
+ "CollPropertyByte": [50, 200, 249],
+ "CollPropertySByte": [-120, 120, 126],
+ "CollPropertyInt16": [1000, 2000, 30112],
+ "CollPropertyInt32": [23232323, 11223355, 10000001],
+ "CollPropertyInt64": [929292929292, 333333333333, 444444444444],
+ "CollPropertySingle": [1.79000000E+03, 2.66000000E+04, 3.21000000E+03],
+ "CollPropertyDouble": [-1.7900000000000000E+04, -2.7800000000000000E+07, 3.2100000000000000E+03],
+ "CollPropertyDecimal": [12, -2, 1234],
+ "CollPropertyBinary": ["q83v", "ASNF", "VGeJ"],
+ "CollPropertyDate": ["1958-12-03", "1999-08-05", "2013-06-25"],
+ "CollPropertyDateTimeOffset": ["2015-08-12T03:08:34Z", "1970-03-28T12:11:10Z", "1948-02-17T09:09:09Z"],
+ "CollPropertyDuration": ["P0DT0H0M13S", "P0DT5H28M20S", "P0DT1H0M0S"],
+ "CollPropertyGuid": ["ffffff67-89ab-cdef-0123-456789aaaaaa", "eeeeee67-89ab-cdef-0123-456789bbbbbb", "cccccc67-89ab-cdef-0123-456789cccccc"],
+ "CollPropertyTimeOfDay": ["04:14:13", "23:59:59", "01:12:33"]
+ },
+ {
+ "PropertyInt16": 3,
+ "CollPropertyString": ["spiderman@comic.com", "spidermaus@comic.com", "spidergirl@comic.com"],
+ "CollPropertyBoolean": [true, false, true],
+ "CollPropertyByte": [50, 200, 249],
+ "CollPropertySByte": [-120, 120, 126],
+ "CollPropertyInt16": [1000, 2000, 30112],
+ "CollPropertyInt32": [23232323, 11223355, 10000001],
+ "CollPropertyInt64": [929292929292, 333333333333, 444444444444],
+ "CollPropertySingle": [1.79000000E+03, 2.66000000E+04, 3.21000000E+03],
+ "CollPropertyDouble": [-1.7900000000000000E+04, -2.7800000000000000E+07, 3.2100000000000000E+03],
+ "CollPropertyDecimal": [12, -2, 1234],
+ "CollPropertyBinary": ["q83v", "ASNF", "VGeJ"],
+ "CollPropertyDate": ["1958-12-03", "1999-08-05", "2013-06-25"],
+ "CollPropertyDateTimeOffset": ["2015-08-12T03:08:34Z", "1970-03-28T12:11:10Z", "1948-02-17T09:09:09Z"],
+ "CollPropertyDuration": ["P0DT0H0M13S", "P0DT5H28M20S", "P0DT1H0M0S"],
+ "CollPropertyGuid": ["ffffff67-89ab-cdef-0123-456789aaaaaa", "eeeeee67-89ab-cdef-0123-456789bbbbbb", "cccccc67-89ab-cdef-0123-456789cccccc"],
+ "CollPropertyTimeOfDay": ["04:14:13", "23:59:59", "01:12:33"]
+ }
+]}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ca91891/lib/server-tecsvc/src/main/resources/ESCompAllPrim.json
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/resources/ESCompAllPrim.json b/lib/server-tecsvc/src/main/resources/ESCompAllPrim.json
new file mode 100644
index 0000000..bd87bc3
--- /dev/null
+++ b/lib/server-tecsvc/src/main/resources/ESCompAllPrim.json
@@ -0,0 +1,65 @@
+{"@odata.context": "$metadata#ESCompAllPrim", "value": [
+ {
+ "PropertyInt16": 32767,
+ "PropertyComp": {
+ "PropertyString": "First Resource - first",
+ "PropertyBinary": "ASNFZ4mrze8=",
+ "PropertyBoolean": true,
+ "PropertyByte": 255,
+ "PropertyDate": "2012-10-03",
+ "PropertyDateTimeOffset": "2012-10-03T07:16:23.1234567Z",
+ "PropertyDecimal": 34.27,
+ "PropertySingle": 1.79000000E+20,
+ "PropertyDouble": -1.7900000000000000E+19,
+ "PropertyDuration": "P0DT0H0M6S",
+ "PropertyGuid": "01234567-89ab-cdef-0123-456789abcdef",
+ "PropertyInt16": 32767,
+ "PropertyInt32": 2147483647,
+ "PropertyInt64": 9223372036854775807,
+ "PropertySByte": 127,
+ "PropertyTimeOfDay": "01:00:01"
+ }
+ },
+ {
+ "PropertyInt16": 7,
+ "PropertyComp": {
+ "PropertyString": "Second Resource - second",
+ "PropertyBinary": "ASNFZ4mrze8=",
+ "PropertyBoolean": true,
+ "PropertyByte": 255,
+ "PropertyDate": "2013-11-04",
+ "PropertyDateTimeOffset": "2013-11-04T07:16:23Z",
+ "PropertyDecimal": 34.27,
+ "PropertySingle": 1.79000000E+20,
+ "PropertyDouble": -1.7900000000000000E+02,
+ "PropertyDuration": "P0DT0H0M6S",
+ "PropertyGuid": "01234567-89ab-cdef-0123-456789abcdef",
+ "PropertyInt16": 25,
+ "PropertyInt32": 2147483647,
+ "PropertyInt64": 9223372036854775807,
+ "PropertySByte": 127,
+ "PropertyTimeOfDay": "07:45:12.7654321"
+ }
+ },
+ {
+ "PropertyInt16": 0,
+ "PropertyComp": {
+ "PropertyString": "Third Resource - third",
+ "PropertyBinary": "ASNFZ4mrze8=",
+ "PropertyBoolean": true,
+ "PropertyByte": 255,
+ "PropertyDate": "2014-12-05",
+ "PropertyDateTimeOffset": "2014-12-05T08:17:45.1234567Z",
+ "PropertyDecimal": 17.98,
+ "PropertySingle": 1.79000000E+20,
+ "PropertyDouble": -1.7900000000000000E+02,
+ "PropertyDuration": "P0DT0H0M6S",
+ "PropertyGuid": "01234567-89ab-cdef-0123-456789abcdef",
+ "PropertyInt16": -25,
+ "PropertyInt32": 2147483647,
+ "PropertyInt64": 9223372036854775807,
+ "PropertySByte": 127,
+ "PropertyTimeOfDay": "13:27:45"
+ }
+ }
+]}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ca91891/lib/server-tecsvc/src/main/resources/ESMixPrimCollComp.json
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/resources/ESMixPrimCollComp.json b/lib/server-tecsvc/src/main/resources/ESMixPrimCollComp.json
new file mode 100644
index 0000000..a58c603
--- /dev/null
+++ b/lib/server-tecsvc/src/main/resources/ESMixPrimCollComp.json
@@ -0,0 +1,68 @@
+{"@odata.context": "$metadata#ESMixPrimCollComp", "value": [
+ {
+ "PropertyInt16": 32767,
+ "CollPropertyString": ["spiderman@comic.com", "spidermaus@comic.com", "spidergirl@comic.com"],
+ "PropertyComp": {
+ "PropertyInt16": 111,
+ "PropertyString": "TEST A"
+ },
+ "CollPropertyComp": [
+ {
+ "PropertyInt16": 123,
+ "PropertyString": "TEST 1"
+ },
+ {
+ "PropertyInt16": 456,
+ "PropertyString": "TEST 2"
+ },
+ {
+ "PropertyInt16": 789,
+ "PropertyString": "TEST 3"
+ }
+ ]
+ },
+ {
+ "PropertyInt16": 7,
+ "CollPropertyString": ["spiderman@comic.com", "spidermaus@comic.com", "spidergirl@comic.com"],
+ "PropertyComp": {
+ "PropertyInt16": 222,
+ "PropertyString": "TEST B"
+ },
+ "CollPropertyComp": [
+ {
+ "PropertyInt16": 123,
+ "PropertyString": "TEST 1"
+ },
+ {
+ "PropertyInt16": 456,
+ "PropertyString": "TEST 2"
+ },
+ {
+ "PropertyInt16": 789,
+ "PropertyString": "TEST 3"
+ }
+ ]
+ },
+ {
+ "PropertyInt16": 0,
+ "CollPropertyString": ["spiderman@comic.com", "spidermaus@comic.com", "spidergirl@comic.com"],
+ "PropertyComp": {
+ "PropertyInt16": 333,
+ "PropertyString": "TEST C"
+ },
+ "CollPropertyComp": [
+ {
+ "PropertyInt16": 123,
+ "PropertyString": "TEST 1"
+ },
+ {
+ "PropertyInt16": 456,
+ "PropertyString": "TEST 2"
+ },
+ {
+ "PropertyInt16": 789,
+ "PropertyString": "TEST 3"
+ }
+ ]
+ }
+]}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ca91891/lib/server-tecsvc/src/main/resources/ESTwoPrim.json
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/resources/ESTwoPrim.json b/lib/server-tecsvc/src/main/resources/ESTwoPrim.json
new file mode 100644
index 0000000..727c6a8
--- /dev/null
+++ b/lib/server-tecsvc/src/main/resources/ESTwoPrim.json
@@ -0,0 +1 @@
+{"@odata.context":"$metadata#ESTwoPrim","value":[{"PropertyInt16":32766,"PropertyString":"Test String1"},{"PropertyInt16":-365,"PropertyString":"Test String2"},{"PropertyInt16":-32766,"PropertyString":"Test String3"},{"PropertyInt16":32767,"PropertyString":"Test String4"}]}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ca91891/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/JsonDataProviderTest.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/JsonDataProviderTest.java b/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/JsonDataProviderTest.java
new file mode 100644
index 0000000..9ac0be6
--- /dev/null
+++ b/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/JsonDataProviderTest.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.tecsvc.data;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntitySet;
+import org.apache.olingo.commons.api.data.LinkedComplexValue;
+import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edm.EdmComplexType;
+import org.apache.olingo.commons.api.edm.EdmElement;
+import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmStructuredType;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.core.serializer.json.ODataJsonSerializer;
+import org.apache.olingo.server.tecsvc.provider.ContainerProvider;
+import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.InputStream;
+import java.util.List;
+
+/**
+ */
+public class JsonDataProviderTest {
+
+ @Test
+ public void doRoundTrip() throws Exception {
+ doRoundTrip("ESAllPrim", 1405);
+ doRoundTrip("ESCompAllPrim", 1597);
+ doRoundTrip("ESCollAllPrim", 2858);
+ doRoundTrip("ESMixPrimCollComp", 1050);
+ }
+
+ @Test
+ public void esAllPrimEntity() throws Exception {
+ DataProvider jdp = getDataProvider();
+ jdp.reset();
+ Entity first = jdp.read("ESAllPrim", Integer.valueOf(0));
+
+ Assert.assertEquals(16, first.getProperties().size());
+ }
+
+ @Test
+ public void esAllPrim() throws Exception {
+ DataProvider jdp = getDataProvider();
+ EntitySet outSet = jdp.readAll("ESAllPrim");
+
+ Assert.assertEquals(3, outSet.getEntities().size());
+ Entity first = outSet.getEntities().get(0);
+ Assert.assertEquals(16, first.getProperties().size());
+ Assert.assertEquals(16, outSet.getEntities().get(1).getProperties().size());
+ Assert.assertEquals(16, outSet.getEntities().get(2).getProperties().size());
+ }
+
+ @Test
+ public void esCollAllPrim() throws Exception {
+ DataProvider jdp = getDataProvider();
+ EntitySet outSet = jdp.readAll("ESCollAllPrim");
+
+ Assert.assertEquals(3, outSet.getEntities().size());
+ Assert.assertEquals(17, outSet.getEntities().get(0).getProperties().size());
+ Property list = outSet.getEntities().get(0).getProperties().get(1);
+ Assert.assertTrue(list.isCollection());
+ Assert.assertEquals(3, list.asCollection().size());
+ Assert.assertEquals(17, outSet.getEntities().get(1).getProperties().size());
+ Assert.assertEquals(17, outSet.getEntities().get(2).getProperties().size());
+ }
+
+ @Test
+ public void esCompAllPrim() throws Exception {
+ DataProvider jdp = getDataProvider();
+ EntitySet outSet = jdp.readAll("ESCompAllPrim");
+
+ Assert.assertEquals(3, outSet.getEntities().size());
+ Assert.assertEquals(2, outSet.getEntities().get(0).getProperties().size());
+ Property complex = outSet.getEntities().get(0).getProperties().get(1);
+ Assert.assertTrue(complex.isLinkedComplex());
+ Assert.assertEquals(16, complex.asLinkedComplex().getValue().size());
+ Assert.assertEquals(2, outSet.getEntities().get(1).getProperties().size());
+ Assert.assertEquals(2, outSet.getEntities().get(2).getProperties().size());
+ }
+
+ @Test
+ public void esMixPrimCollComp() throws Exception {
+ DataProvider jdp = getDataProvider();
+ EntitySet outSet = jdp.readAll("ESMixPrimCollComp");
+
+ Assert.assertEquals(3, outSet.getEntities().size());
+ Assert.assertEquals(4, outSet.getEntities().get(0).getProperties().size());
+ Property complex = outSet.getEntities().get(0).getProperties().get(2);
+ Assert.assertTrue(complex.isLinkedComplex());
+ Assert.assertEquals(2, complex.asLinkedComplex().getValue().size());
+ Property complexCollection = outSet.getEntities().get(0).getProperties().get(3);
+ Assert.assertTrue(complexCollection.isCollection());
+ List<?> linkedComplexValues = complexCollection.asCollection();
+ Assert.assertEquals(3, linkedComplexValues.size());
+ LinkedComplexValue linkedComplexValue = (LinkedComplexValue) linkedComplexValues.get(0);
+ Assert.assertEquals(2, linkedComplexValue.getValue().size());
+ Property lcProp = linkedComplexValue.getValue().get(0);
+ Assert.assertFalse(lcProp.isCollection());
+ Assert.assertEquals(Short.valueOf("123"), lcProp.getValue());
+ //
+ Assert.assertEquals(4, outSet.getEntities().get(1).getProperties().size());
+ Assert.assertEquals(4, outSet.getEntities().get(2).getProperties().size());
+ }
+
+ private DataProvider getDataProvider() throws DataProvider.DataProviderException {
+ OData odata = OData.newInstance();
+ Edm edm = odata.createEdm(new EdmTechProvider());
+ return new JefDataProvider(edm);
+ }
+
+ @Test
+ public void edm() {
+ OData odata = OData.newInstance();
+ Edm edm = odata.createEdm(new EdmTechProvider());
+ EdmEntitySet edmEntitySet =
+ edm.getEntityContainer(ContainerProvider.nameContainer).getEntitySet("ESCompAllPrim");
+
+ EdmEntityType et = edmEntitySet.getEntityType();
+ printType(edm, et);
+ }
+
+ private void printType(Edm edm, EdmStructuredType type) {
+
+ List<String> propNames = type.getPropertyNames();
+
+ for (String propName : propNames) {
+ EdmElement element = type.getProperty(propName);
+ if(element instanceof EdmProperty) {
+ EdmProperty property = (EdmProperty) element;
+ if(property.isPrimitive()) {
+ System.out.println("Primitive name/type: " + property.getName() + "/" + property.getType());
+ } else {
+ // recursion
+ EdmComplexType complex = edm.getComplexType(property.getType().getFullQualifiedName());
+ System.out.println("Complex name/type [" + property.getName() + "/" + property.getType() + "]");
+ printType(edm, complex);
+ }
+ }
+ }
+ }
+
+ private void doRoundTrip(String name, int expectedLength) throws Exception {
+ OData odata = OData.newInstance();
+ Edm edm = odata.createEdm(new EdmTechProvider());
+ EdmEntitySet edmEntitySet = edm.getEntityContainer(ContainerProvider.nameContainer).getEntitySet(name);
+
+ DataProvider jdp = new JefDataProvider(edm);
+ EntitySet outSet = jdp.readAll(name);
+
+
+ ODataJsonSerializer serializer = new ODataJsonSerializer();
+ ContextURL contextUrl = null;
+ InputStream is = serializer.entitySet(edmEntitySet, outSet, contextUrl);
+
+ StringHelper.Stream stream = StringHelper.toStream(is);
+
+ System.out.println("========== " + name + " =================");
+ stream.print();
+ System.out.println("\n========== " + name + " =================");
+
+ Assert.assertEquals(expectedLength, stream.asString().length());
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ca91891/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/StringHelper.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/StringHelper.java b/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/StringHelper.java
new file mode 100644
index 0000000..52c4599
--- /dev/null
+++ b/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/StringHelper.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * 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.tecsvc.data;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.util.Random;
+
+/**
+ *
+ */
+public class StringHelper {
+
+ 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 String asString() {
+ return asString("UTF-8");
+ }
+
+ 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);
+ }
+
+ /**
+ * 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) {
+ try {
+ return new Stream(content, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 should be supported on each system.");
+ }
+ }
+
+ public static String inputStreamToString(final InputStream in, final boolean preserveLineBreaks) throws IOException {
+ final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in, Charset.forName("UTF-8")));
+ final StringBuilder stringBuilder = new StringBuilder();
+ String line = null;
+
+ while ((line = bufferedReader.readLine()) != null) {
+ stringBuilder.append(line);
+ if (preserveLineBreaks) {
+ stringBuilder.append("\n");
+ }
+ }
+
+ bufferedReader.close();
+
+ final String result = stringBuilder.toString();
+
+ return result;
+ }
+
+ public static int countLines(final String content) {
+ return countLines(content, "\r\n");
+ }
+
+ 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;
+ }
+
+ public static String inputStreamToString(final InputStream in) throws IOException {
+ return inputStreamToString(in, false);
+ }
+
+ /**
+ * 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, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // we know that UTF-8 is supported
+ throw new TestUtilRuntimeException("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();
+ }
+
+ private static class TestUtilRuntimeException extends RuntimeException {
+ public TestUtilRuntimeException(String message, Throwable cause) {
+ }
+ }
+}
[2/2] git commit: [OLINGO-317] Merge feature branch into master
Posted by mi...@apache.org.
[OLINGO-317] Merge feature branch into master
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/45b7289f
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/45b7289f
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/45b7289f
Branch: refs/heads/master
Commit: 45b7289f88da120e6911c60bf52ed64d753183bf
Parents: b3cfc35 3ca9189
Author: Michael Bolz <mi...@sap.com>
Authored: Tue Jul 8 13:53:58 2014 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Tue Jul 8 13:53:58 2014 +0200
----------------------------------------------------------------------
.../core/serializer/json/JsonDataProvider.java | 46 +++
.../json/ODataJsonSerializerTest.java | 28 +-
.../olingo/server/tecsvc/TechnicalServlet.java | 27 +-
.../olingo/server/tecsvc/data/DataProvider.java | 25 +-
.../server/tecsvc/data/JefDataProvider.java | 349 +++++++++++++++++++
.../tecsvc/processor/SampleJsonProcessor.java | 232 ------------
.../tecsvc/processor/TechnicalProcessor.java | 131 ++++++-
.../tecsvc/provider/PropertyProvider.java | 3 +
.../src/main/resources/ESAllPrim.json | 56 +++
.../src/main/resources/ESCollAllPrim.json | 59 ++++
.../src/main/resources/ESCompAllPrim.json | 65 ++++
.../src/main/resources/ESMixPrimCollComp.json | 68 ++++
.../src/main/resources/ESTwoPrim.json | 1 +
.../tecsvc/data/JsonDataProviderTest.java | 186 ++++++++++
.../olingo/server/tecsvc/data/StringHelper.java | 206 +++++++++++
15 files changed, 1198 insertions(+), 284 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/45b7289f/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
----------------------------------------------------------------------
diff --cc lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
index 7c5a267,0b2c6bd..775d96e
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
@@@ -28,29 -32,129 +32,126 @@@ import org.apache.olingo.server.api.ODa
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.processor.CollectionProcessor;
import org.apache.olingo.server.api.processor.EntityProcessor;
+ import org.apache.olingo.server.api.serializer.ODataSerializer;
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.UriResourceKind;
import org.apache.olingo.server.tecsvc.data.DataProvider;
-import org.apache.olingo.server.tecsvc.data.JefDataProvider;
+ import org.apache.olingo.server.tecsvc.provider.ContainerProvider;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+
+ import java.net.URI;
+ import java.net.URISyntaxException;
+ import java.util.List;
public class TechnicalProcessor implements CollectionProcessor, EntityProcessor {
- public TechnicalProcessor(final DataProvider dataProvider) {}
-
+ private static final Logger LOG = LoggerFactory.getLogger(TechnicalProcessor.class);
- @Override
- public void init(final OData odata, final Edm edm) {}
+ private OData odata;
+ private Edm edm;
+ private DataProvider dataProvider;
+
+ public TechnicalProcessor(final DataProvider dataProvider) {
+ this.dataProvider = dataProvider;
+ }
@Override
- public void readEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
- final ContentType requestedContentType) {
- response.setContent(new ByteArrayInputStream("Entity".getBytes()));
- response.setStatusCode(200);
- response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
+ public void init(OData odata, Edm edm) {
+ this.odata = odata;
+ this.edm = edm;
}
@Override
- public void readCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
+ public void readCollection(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
- final ContentType requestedContentType) {
- response.setContent(new ByteArrayInputStream("EntitySet".getBytes()));
- response.setStatusCode(200);
- response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
++ final ContentType requestedContentType) {
+ long time = System.nanoTime();
+
+ LOG.info((System.nanoTime() - time) / 1000 + " microseconds");
+ time = System.nanoTime();
+ ODataSerializer serializer = odata.createSerializer(ODataFormat.JSON);
+ EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo);
+ ContextURL contextUrl = getContextUrl(request, edmEntitySet.getEntityType());
+ try {
+ EntitySet entitySet = readEntitySetInternal(edmEntitySet, contextUrl);
+ if(entitySet == null) {
+ response.setStatusCode(HttpStatusCode.NOT_FOUND.getStatusCode());
+ } else {
+ response.setContent(serializer.entitySet(edmEntitySet, entitySet, contextUrl));
+ LOG.info("Finished in " + (System.nanoTime() - time) / 1000 + " microseconds");
+
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader("Content-Type", ContentType.APPLICATION_JSON.toContentTypeString());
+ }
+ } catch (DataProvider.DataProviderException e) {
+ response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
+ }
+ }
+
+ @Override
- public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, String format) {
++ public void readEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
++ final ContentType requestedContentType) {
+ long time = System.nanoTime();
+
+ LOG.info((System.nanoTime() - time) / 1000 + " microseconds");
+ time = System.nanoTime();
+ ODataSerializer serializer = odata.createSerializer(ODataFormat.JSON);
+ EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo);
+ try {
+ Entity entity = readEntityInternal(uriInfo, edmEntitySet);
+ if(entity == null) {
+ response.setStatusCode(HttpStatusCode.NOT_FOUND.getStatusCode());
+ } else {
+ response.setContent(serializer.entity(edmEntitySet.getEntityType(), entity,
+ getContextUrl(request, edmEntitySet.getEntityType())));
+ LOG.info("Finished in " + (System.nanoTime() - time) / 1000 + " microseconds");
+
+ response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+ response.setHeader("Content-Type", ContentType.APPLICATION_JSON.toContentTypeString());
+ }
+ } catch (DataProvider.DataProviderException e) {
+ response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
+ }
+ }
+
+ private Entity readEntityInternal(UriInfo uriInfo, EdmEntitySet entitySet)
+ throws DataProvider.DataProviderException {
+ List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+ if(!resourcePaths.isEmpty()) {
+ UriResource res = resourcePaths.get(resourcePaths.size()-1);
+ if(res.getKind() == UriResourceKind.entitySet) {
+ UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) res;
+ String key = resourceEntitySet.getKeyPredicates().get(0).getText();
+ return dataProvider.read(entitySet.getName(), key);
+ }
+ }
+ throw new RuntimeException("Invalid resource paths.. " + resourcePaths);
+ }
+
+ private ContextURL getContextUrl(ODataRequest request, EdmEntityType entityType) {
+ return ContextURL.getInstance(URI.create(request.getRawBaseUri() + "/" + entityType.getName()));
+ }
+
+ private EntitySet readEntitySetInternal(EdmEntitySet edmEntitySet, ContextURL contextUrl)
+ throws DataProvider.DataProviderException {
+ EntitySet entitySet = dataProvider.readAll(edmEntitySet.getName());
+ try {
+ entitySet.setNext(new URI(contextUrl.getServiceRoot().toASCIIString() + "/" +
+ edmEntitySet.getEntityType().getName()));
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Invalid uri syntax.", e);
+ }
+ return entitySet;
+ }
+
+ private EdmEntitySet getEdmEntitySet(UriInfo uriInfo) {
+ List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
+ if(resourcePaths.isEmpty()) {
+ throw new RuntimeException("Invalid resource path.");
+ }
+ String entitySetName = resourcePaths.get(resourcePaths.size()-1).toString();
+ return edm.getEntityContainer(ContainerProvider.nameContainer).getEntitySet(entitySetName);
}
}