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/04/04 19:05:29 UTC
[23/50] [abbrv] olingo-odata4 git commit: OLINGO-573: New processing
framework on server side with single interface with TripPin example
OLINGO-573: New processing framework on server side with single interface with TripPin example
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/8668b097
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/8668b097
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/8668b097
Branch: refs/heads/OLINGO-549-ODataV4-JPA
Commit: 8668b097192674b47ba48e8978633665858f5d32
Parents: 62f1001
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Mon Mar 30 12:40:32 2015 -0500
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Mon Mar 30 12:40:32 2015 -0500
----------------------------------------------------------------------
.../ExpandWithSystemQueryOptionsITCase.java | 65 +-
.../apache/olingo/commons/core/DecoderTest.java | 10 +-
.../apache/olingo/commons/core/EncoderTest.java | 10 +-
lib/pom.xml | 1 +
.../api/deserializer/ODataDeserializer.java | 31 +-
.../EntityCollectionSerializerOptions.java | 18 +-
.../api/serializer/EntitySerializerOptions.java | 18 +-
.../server/api/serializer/ODataSerializer.java | 26 +-
.../api/serializer/SerializerException.java | 8 +-
lib/server-core-ext/pom.xml | 117 +++
.../apache/olingo/server/core/ErrorHandler.java | 125 +++
.../olingo/server/core/MetadataParser.java | 679 +++++++++++++++
.../olingo/server/core/OData4HttpHandler.java | 123 +++
.../apache/olingo/server/core/OData4Impl.java | 45 +
.../server/core/RequestURLHierarchyVisitor.java | 333 ++++++++
.../olingo/server/core/RequestURLVisitor.java | 127 +++
.../server/core/ReturnRepresentation.java | 23 +
.../server/core/SchemaBasedEdmProvider.java | 303 +++++++
.../olingo/server/core/ServiceDispatcher.java | 227 +++++
.../olingo/server/core/ServiceHandler.java | 263 ++++++
.../olingo/server/core/ServiceRequest.java | 253 ++++++
.../core/legacy/ProcessorServiceHandler.java | 433 ++++++++++
.../server/core/requests/ActionRequest.java | 120 +++
.../server/core/requests/BatchRequest.java | 197 +++++
.../server/core/requests/DataRequest.java | 769 +++++++++++++++++
.../server/core/requests/FunctionRequest.java | 122 +++
.../server/core/requests/MediaRequest.java | 99 +++
.../server/core/requests/MetadataRequest.java | 61 ++
.../server/core/requests/OperationRequest.java | 118 +++
.../core/requests/ServiceDocumentRequest.java | 57 ++
.../server/core/responses/CountResponse.java | 60 ++
.../server/core/responses/EntityResponse.java | 140 +++
.../core/responses/EntitySetResponse.java | 82 ++
.../server/core/responses/MetadataResponse.java | 62 ++
.../core/responses/NoContentResponse.java | 100 +++
.../core/responses/PrimitiveValueResponse.java | 105 +++
.../server/core/responses/PropertyResponse.java | 144 ++++
.../core/responses/ServiceDocumentResponse.java | 63 ++
.../server/core/responses/ServiceResponse.java | 119 +++
.../core/responses/ServiceResponseVisior.java | 71 ++
.../server/core/responses/StreamResponse.java | 54 ++
.../olingo/server/core/MetadataParserTest.java | 185 ++++
.../server/core/ServiceDispatcherTest.java | 417 +++++++++
.../olingo/server/example/TripPinDataModel.java | 843 +++++++++++++++++++
.../olingo/server/example/TripPinHandler.java | 546 ++++++++++++
.../server/example/TripPinServiceTest.java | 756 +++++++++++++++++
.../olingo/server/example/TripPinServlet.java | 75 ++
.../src/test/resources/OlingoOrangeTM.png | Bin 0 -> 93316 bytes
.../src/test/resources/airlines.json | 64 ++
.../src/test/resources/airports.json | 394 +++++++++
.../src/test/resources/event.json | 157 ++++
.../src/test/resources/flight-links.json | 52 ++
.../src/test/resources/flight.json | 66 ++
.../src/test/resources/people-links.json | 94 +++
.../src/test/resources/people.json | 323 +++++++
.../src/test/resources/photos.json | 64 ++
.../src/test/resources/trip-links.json | 28 +
.../src/test/resources/trip.json | 224 +++++
.../src/test/resources/trippin.xml | 356 ++++++++
.../json/ODataJsonDeserializer.java | 86 +-
.../serializer/json/ODataJsonSerializer.java | 138 ++-
.../serializer/utils/ContextURLBuilder.java | 9 +-
.../serializer/xml/ODataXmlSerializerImpl.java | 19 +-
.../server/core/uri/UriResourceActionImpl.java | 14 +-
.../server/core/uri/validator/UriValidator.java | 8 +-
.../server-core-exceptions-i18n.properties | 2 +
.../json/ODataJsonDeserializerBasicTest.java | 38 +-
.../json/ODataJsonSerializerTest.java | 13 +-
.../olingo/server/tecsvc/TechnicalServlet.java | 8 +-
.../olingo/server/tecsvc/data/DataCreator.java | 134 ++-
.../olingo/server/tecsvc/data/DataProvider.java | 31 +-
.../olingo/server/tecsvc/data/FunctionData.java | 7 +-
.../processor/TechnicalEntityProcessor.java | 28 +-
.../TechnicalPrimitiveComplexProcessor.java | 15 +-
.../server/tecsvc/data/DataProviderTest.java | 2 +-
.../json/ODataJsonDeserializerEntityTest.java | 4 +-
.../json/ODataJsonSerializerTest.java | 60 +-
.../core/uri/antlr/TestUriParserImpl.java | 11 +-
.../core/uri/validator/UriValidatorTest.java | 18 +-
.../olingo/server/sample/data/DataProvider.java | 13 +-
.../server/sample/processor/CarsProcessor.java | 16 +-
81 files changed, 10840 insertions(+), 259 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
index 2db9535..e5ad3ca 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ExpandWithSystemQueryOptionsITCase.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
@@ -69,13 +69,16 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
entity.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
if (propInt16.equals(1) && propString.equals("1")) {
- assertEquals(1, inlineEntitySet.getEntities().size());
- final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
-
- assertEquals(1, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
- assertEquals("2", inlineEntity.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
+ assertEquals(2, inlineEntitySet.getEntities().size());
+ for (ODataEntity e:inlineEntitySet.getEntities()) {
+ assertEquals(1, e.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+ String strValue = (String)e.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue();
+ if (!strValue.equals("2") && !strValue.equals("1")) {
+ fail();
+ }
+ }
} else if (propInt16.equals(1) && propString.equals("2")) {
- assertEquals(0, inlineEntitySet.getEntities().size());
+ assertEquals(1, inlineEntitySet.getEntities().size());
} else if (propInt16.equals(2) && propString.equals("1")) {
assertEquals(1, inlineEntitySet.getEntities().size());
final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
@@ -108,14 +111,13 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
if (propInt16.equals(1) && propString.equals("1")) {
assertEquals(2, inlineEntitySet.getEntities().size());
- final ODataEntity inlineEntity1 = inlineEntitySet.getEntities().get(0);
- final ODataEntity inlineEntity2 = inlineEntitySet.getEntities().get(1);
-
- assertEquals(1, inlineEntity1.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
- assertEquals("2", inlineEntity1.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
-
- assertEquals(1, inlineEntity2.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
- assertEquals("1", inlineEntity2.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
+ for (ODataEntity e:inlineEntitySet.getEntities()) {
+ assertEquals(1, e.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+ String strValue = (String)e.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue();
+ if (!strValue.equals("2") && !strValue.equals("1")) {
+ fail();
+ }
+ }
}
}
}
@@ -136,15 +138,15 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
entity.getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
if (propInt16.equals(1)) {
- assertEquals(1, inlineEntitySet.getEntities().size());
+ assertEquals(2, inlineEntitySet.getEntities().size());
final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
- assertEquals(2, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+ assertEquals(1, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
} else if (propInt16.equals(2)) {
- assertEquals(1, inlineEntitySet.getEntities().size());
+ assertEquals(2, inlineEntitySet.getEntities().size());
final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
- assertEquals(3, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+ assertEquals(2, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
} else if (propInt16.equals(3)) {
assertEquals(0, inlineEntitySet.getEntities().size());
}
@@ -167,12 +169,12 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
entity.getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
if (propInt16.equals(1)) {
- assertEquals(1, inlineEntitySet.getEntities().size());
+ assertEquals(2, inlineEntitySet.getEntities().size());
final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
assertEquals(1, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
} else if (propInt16.equals(2)) {
- assertEquals(1, inlineEntitySet.getEntities().size());
+ assertEquals(2, inlineEntitySet.getEntities().size());
final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
assertEquals(2, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
@@ -201,15 +203,18 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
entity.getNavigationLink(NAV_PROPERTY_ET_TWO_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
if (propInt16.equals(1) && propString.equals("1")) {
- assertEquals(1, inlineEntitySet.getEntities().size());
- final ODataEntity inlineEntity = inlineEntitySet.getEntities().get(0);
-
- assertEquals(1, inlineEntity.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
- assertEquals("2", inlineEntity.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue());
+ assertEquals(2, inlineEntitySet.getEntities().size());
+ for (ODataEntity e:inlineEntitySet.getEntities()) {
+ assertEquals(1, e.getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
+ String strValue = (String)e.getProperty(PROPERTY_STRING).getPrimitiveValue().toValue();
+ if (!strValue.equals("2") && !strValue.equals("1")) {
+ fail();
+ }
+ }
} else if (propInt16.equals(1) && propString.equals("2")) {
- assertEquals(0, inlineEntitySet.getEntities().size());
+ assertEquals(1, inlineEntitySet.getEntities().size());
} else if (propInt16.equals(2) && propString.equals("1")) {
- assertEquals(0, inlineEntitySet.getEntities().size());
+ assertEquals(1, inlineEntitySet.getEntities().size());
} else if (propInt16.equals(3) && propString.equals("1")) {
assertEquals(0, inlineEntitySet.getEntities().size());
} else {
@@ -274,7 +279,7 @@ public class ExpandWithSystemQueryOptionsITCase extends AbstractBaseTestITCase {
final ODataEntitySet entitySet =
response.getBody().getNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY).asInlineEntitySet().getEntitySet();
- assertEquals(1, entitySet.getEntities().size());
+ assertEquals(2, entitySet.getEntities().size());
assertEquals(1, entitySet.getEntities().get(0).getProperty(PROPERTY_INT16).getPrimitiveValue().toValue());
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/commons-core/src/test/java/org/apache/olingo/commons/core/DecoderTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/DecoderTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/DecoderTest.java
index 019ef5a..09f2326 100644
--- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/DecoderTest.java
+++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/DecoderTest.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,13 +18,13 @@
******************************************************************************/
package org.apache.olingo.commons.core;
-import org.junit.Test;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
+import org.junit.Test;
+
/**
- *
+ *
*/
public class DecoderTest {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/commons-core/src/test/java/org/apache/olingo/commons/core/EncoderTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/EncoderTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/EncoderTest.java
index 74eb1af..7db30ce 100644
--- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/EncoderTest.java
+++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/EncoderTest.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,16 +18,16 @@
******************************************************************************/
package org.apache.olingo.commons.core;
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
import java.net.URI;
import java.net.URISyntaxException;
-import static org.junit.Assert.assertEquals;
+import org.junit.Test;
/**
* Tests for percent-encoding.
- *
+ *
*/
public class EncoderTest {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/pom.xml
----------------------------------------------------------------------
diff --git a/lib/pom.xml b/lib/pom.xml
index 6843ff3..d1e8864 100644
--- a/lib/pom.xml
+++ b/lib/pom.xml
@@ -42,6 +42,7 @@
<module>client-core</module>
<module>server-api</module>
<module>server-core</module>
+ <module>server-core-ext</module>
<module>server-tecsvc</module>
<module>server-test</module>
</modules>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/ODataDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/ODataDeserializer.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/ODataDeserializer.java
index d5f7343..3bbcc66 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/ODataDeserializer.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/deserializer/ODataDeserializer.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
@@ -19,11 +19,15 @@
package org.apache.olingo.server.api.deserializer;
import java.io.InputStream;
+import java.net.URI;
+import java.util.List;
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.edm.EdmAction;
import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmProperty;
/**
* Deserializer on OData server side.
@@ -32,7 +36,7 @@ public interface ODataDeserializer {
/**
* Deserializes an entity stream into an {@link Entity} object.
- * Validates: property types, no double properties, correct json types
+ * Validates: property types, no double properties, correct json types
* @param stream
* @param edmEntityType
* @return deserialized {@link Entity} object
@@ -48,7 +52,7 @@ public interface ODataDeserializer {
* @throws DeserializerException
*/
EntitySet entityCollection(InputStream stream, EdmEntityType edmEntityType) throws DeserializerException;
-
+
/**
* Deserializes an action-parameters stream into an {@link Entity} object.
* Validates: parameter types, no double parameters, correct json types.
@@ -58,4 +62,23 @@ public interface ODataDeserializer {
* @throws DeserializerException
*/
Entity actionParameters(InputStream stream, EdmAction edmAction) throws DeserializerException;
+
+
+ /**
+ * Deserializes the Property or collections of properties (primitive & complex)
+ * @param stream
+ * @param edmProperty
+ * @return deserialized {@link Property}
+ * @throws DeserializerException
+ */
+ Property property(InputStream stream, EdmProperty edmProperty) throws DeserializerException;
+
+ /**
+ * Read entity references from the provided document
+ * @param stream
+ * @param keys
+ * @return
+ * @throws DeserializerException
+ */
+ List<URI> entityReferences(InputStream stream) throws DeserializerException;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
index 14c588d..e5dd6b0 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.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
@@ -30,6 +30,7 @@ public class EntityCollectionSerializerOptions {
private CountOption count;
private ExpandOption expand;
private SelectOption select;
+ private boolean onlyReferences;
/** Gets the {@link ContextURL}. */
public ContextURL getContextURL() {
@@ -51,6 +52,11 @@ public class EntityCollectionSerializerOptions {
return select;
}
+ /** only writes the references of the entities*/
+ public boolean onlyReferences() {
+ return onlyReferences;
+ }
+
/** Initializes the options builder. */
public static Builder with() {
return new Builder();
@@ -59,7 +65,7 @@ public class EntityCollectionSerializerOptions {
/** Builder of OData serializer options. */
public static final class Builder {
- private EntityCollectionSerializerOptions options;
+ private final EntityCollectionSerializerOptions options;
private Builder() {
options = new EntityCollectionSerializerOptions();
@@ -89,6 +95,12 @@ public class EntityCollectionSerializerOptions {
return this;
}
+ /** Sets to serialize only references */
+ public Builder setWriteOnlyReferences(final boolean ref) {
+ options.onlyReferences = ref;
+ return this;
+ }
+
/** Builds the OData serializer options. */
public EntityCollectionSerializerOptions build() {
return options;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java
index fcbd150..0abb31c 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.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
@@ -27,6 +27,7 @@ public class EntitySerializerOptions {
private ContextURL contextURL;
private ExpandOption expand;
private SelectOption select;
+ private boolean onlyReferences;
/** Gets the {@link ContextURL}. */
public ContextURL getContextURL() {
@@ -43,6 +44,11 @@ public class EntitySerializerOptions {
return select;
}
+ /** only writes the references of the entities*/
+ public boolean onlyReferences() {
+ return onlyReferences;
+ }
+
private EntitySerializerOptions() {}
/** Initializes the options builder. */
@@ -53,7 +59,7 @@ public class EntitySerializerOptions {
/** Builder of OData serializer options. */
public static final class Builder {
- private EntitySerializerOptions options;
+ private final EntitySerializerOptions options;
private Builder() {
options = new EntitySerializerOptions();
@@ -77,6 +83,12 @@ public class EntitySerializerOptions {
return this;
}
+ /** Sets to serialize only references */
+ public Builder setWriteOnlyReferences(final boolean ref) {
+ options.onlyReferences = ref;
+ return this;
+ }
+
/** Builds the OData serializer options. */
public EntitySerializerOptions build() {
return options;
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java
index 72f8ee8..55377ce 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.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,7 +39,7 @@ public interface ODataSerializer {
/**
* Writes the service document into an InputStream.
* @param edm the Entity Data Model
- * @param serviceRoot the service-root URI of this OData service
+ * @param serviceRoot the service-root URI of this OData service
*/
InputStream serviceDocument(Edm edm, String serviceRoot) throws SerializerException;
@@ -58,21 +58,23 @@ public interface ODataSerializer {
/**
* Writes entity-collection data into an InputStream.
+ * @param metadata Metadata for the service
* @param entityType the {@link EdmEntityType}
* @param entitySet the data of the entity set
* @param options options for the serializer
*/
- InputStream entityCollection(EdmEntityType entityType, EntitySet entitySet,
- EntityCollectionSerializerOptions options) throws SerializerException;
+ InputStream entityCollection(ServiceMetadata metadata, EdmEntityType entityType,
+ EntitySet entitySet, EntityCollectionSerializerOptions options) throws SerializerException;
/**
* Writes entity data into an InputStream.
+ * @param metadata Metadata for the service
* @param entityType the {@link EdmEntityType}
* @param entity the data of the entity
* @param options options for the serializer
*/
- InputStream entity(EdmEntityType entityType, Entity entity, EntitySerializerOptions options)
- throws SerializerException;
+ InputStream entity(ServiceMetadata metadata, EdmEntityType entityType, Entity entity,
+ EntitySerializerOptions options) throws SerializerException;
/**
* Writes primitive-type instance data into an InputStream.
@@ -85,12 +87,13 @@ public interface ODataSerializer {
/**
* Writes complex-type instance data into an InputStream.
+ * @param metadata Metadata for the service
* @param type complex type
* @param property property value
* @param options options for the serializer
*/
- InputStream complex(EdmComplexType type, Property property, ComplexSerializerOptions options)
- throws SerializerException;
+ InputStream complex(ServiceMetadata metadata, EdmComplexType type, Property property,
+ ComplexSerializerOptions options) throws SerializerException;
/**
* Writes data of a collection of primitive-type instances into an InputStream.
@@ -103,10 +106,11 @@ public interface ODataSerializer {
/**
* Writes data of a collection of complex-type instances into an InputStream.
+ * @param metadata Metadata for the service
* @param type complex type
* @param property property value
* @param options options for the serializer
*/
- InputStream complexCollection(EdmComplexType type, Property property, ComplexSerializerOptions options)
- throws SerializerException;
+ InputStream complexCollection(ServiceMetadata metadata, EdmComplexType type, Property property,
+ ComplexSerializerOptions options) throws SerializerException;
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerException.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerException.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerException.java
index 1583241..a7d067f 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerException.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerException.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
@@ -37,7 +37,9 @@ public class SerializerException extends ODataTranslatedException {
/** parameter: property name */ INCONSISTENT_PROPERTY_TYPE,
/** parameter: property name */ MISSING_PROPERTY,
/** parameters: property name, property value */ WRONG_PROPERTY_VALUE,
- /** parameters: primitive-type name, value */ WRONG_PRIMITIVE_VALUE;
+ /** parameters: primitive-type name, value */ WRONG_PRIMITIVE_VALUE,
+ UNKNOWN_TYPE,
+ WRONG_BASE_TYPE;
@Override
public String getKey() {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-core-ext/pom.xml
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/pom.xml b/lib/server-core-ext/pom.xml
new file mode 100644
index 0000000..a5730c0
--- /dev/null
+++ b/lib/server-core-ext/pom.xml
@@ -0,0 +1,117 @@
+<?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/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>odata-server-core-ext</artifactId>
+ <packaging>jar</packaging>
+ <name>${project.artifactId}</name>
+
+ <parent>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>odata-lib</artifactId>
+ <version>4.0.0-beta-03-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <properties>
+ <jetty-version>9.2.7.v20150116</jetty-version>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>odata-server-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>odata-server-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.olingo</groupId>
+ <artifactId>odata-commons-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr4-runtime</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.xml.stream</groupId>
+ <artifactId>stax-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ <scope>test</scope>
+ <version>${jetty-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-servlet</artifactId>
+ <version>${jetty-version}</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-http</artifactId>
+ <version>${jetty-version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-client</artifactId>
+ <scope>test</scope>
+ <version>${jetty-version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ErrorHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ErrorHandler.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ErrorHandler.java
new file mode 100644
index 0000000..199c62d
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/ErrorHandler.java
@@ -0,0 +1,125 @@
+/*
+ * 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;
+
+import java.io.ByteArrayInputStream;
+
+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.ODataRequest;
+import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.ODataServerError;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.batch.exception.BatchDeserializerException;
+import org.apache.olingo.server.api.deserializer.DeserializerException;
+import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+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.uri.parser.Parser;
+import org.apache.olingo.server.core.uri.parser.UriParserException;
+import org.apache.olingo.server.core.uri.parser.UriParserSemanticException;
+import org.apache.olingo.server.core.uri.parser.UriParserSyntaxException;
+import org.apache.olingo.server.core.uri.validator.UriValidationException;
+
+public class ErrorHandler {
+ private final OData odata;
+ private final ServiceMetadata metadata;
+ private final CustomContentTypeSupport customContent;
+
+ public ErrorHandler(OData odata, ServiceMetadata metadata, CustomContentTypeSupport customContent) {
+ this.odata = odata;
+ this.metadata = metadata;
+ this.customContent = customContent;
+ }
+
+ public void handleException(Exception e, ODataRequest request, ODataResponse response) {
+ if (e instanceof UriValidationException) {
+ ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((UriValidationException)e, null);
+ handleServerError(request, response, serverError);
+ } else if(e instanceof UriParserSemanticException) {
+ ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((UriParserSemanticException)e, null);
+ handleServerError(request, response, serverError);
+ } else if(e instanceof UriParserSyntaxException) {
+ ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((UriParserSyntaxException)e, null);
+ handleServerError(request, response, serverError);
+ } else if(e instanceof UriParserException) {
+ ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((UriParserException)e, null);
+ handleServerError(request, response, serverError);
+ } else if(e instanceof ContentNegotiatorException) {
+ ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((ContentNegotiatorException)e, null);
+ handleServerError(request, response, serverError);
+ } else if(e instanceof SerializerException) {
+ ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((SerializerException)e, null);
+ handleServerError(request, response, serverError);
+ } else if(e instanceof BatchDeserializerException) {
+ ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((BatchDeserializerException)e, null);
+ handleServerError(request, response, serverError);
+ } else if(e instanceof DeserializerException) {
+ ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((DeserializerException)e, null);
+ handleServerError(request, response, serverError);
+ } else if(e instanceof ODataHandlerException) {
+ ODataServerError serverError = ODataExceptionHelper.createServerErrorObject((ODataHandlerException)e, null);
+ handleServerError(request, response, serverError);
+ } else {
+ ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e);
+ handleServerError(request, response, serverError);
+ }
+ }
+
+ void handleServerError(final ODataRequest request, final ODataResponse response,
+ final ODataServerError serverError) {
+ ContentType requestedContentType;
+ try {
+ UriInfo uriInfo = new Parser().parseUri(request.getRawODataPath(), request.getRawQueryPath(),
+ null, this.metadata.getEdm());
+ requestedContentType = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
+ request, this.customContent, RepresentationType.ERROR);
+ } catch (final ContentNegotiatorException e) {
+ requestedContentType = ODataFormat.JSON.getContentType();
+ } catch (UriParserException e) {
+ requestedContentType = ODataFormat.JSON.getContentType();
+ }
+ processError(response, serverError, requestedContentType);
+ }
+
+ void processError(ODataResponse response, ODataServerError serverError,
+ ContentType requestedContentType) {
+ try {
+ ODataSerializer serializer = this.odata.createSerializer(ODataFormat
+ .fromContentType(requestedContentType));
+ response.setContent(serializer.error(serverError));
+ response.setStatusCode(serverError.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
+ } catch (Exception e) {
+ // This should never happen but to be sure we have this catch here
+ // to prevent sending a stacktrace to a client.
+ String responseContent = "{\"error\":{\"code\":null,\"message\":\"An unexpected exception occurred during "
+ + "error processing with message: " + e.getMessage() + "\"}}"; //$NON-NLS-1$ //$NON-NLS-2$
+ response.setContent(new ByteArrayInputStream(responseContent.getBytes()));
+ response.setStatusCode(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode());
+ response.setHeader(HttpHeader.CONTENT_TYPE,
+ ContentType.APPLICATION_JSON.toContentTypeString());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
new file mode 100644
index 0000000..e34a28a
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/MetadataParser.java
@@ -0,0 +1,679 @@
+/*
+ * 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;
+
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.provider.Action;
+import org.apache.olingo.commons.api.edm.provider.ActionImport;
+import org.apache.olingo.commons.api.edm.provider.ComplexType;
+import org.apache.olingo.commons.api.edm.provider.EdmProvider;
+import org.apache.olingo.commons.api.edm.provider.EntityContainer;
+import org.apache.olingo.commons.api.edm.provider.EntitySet;
+import org.apache.olingo.commons.api.edm.provider.EntityType;
+import org.apache.olingo.commons.api.edm.provider.EnumMember;
+import org.apache.olingo.commons.api.edm.provider.EnumType;
+import org.apache.olingo.commons.api.edm.provider.Function;
+import org.apache.olingo.commons.api.edm.provider.FunctionImport;
+import org.apache.olingo.commons.api.edm.provider.NavigationProperty;
+import org.apache.olingo.commons.api.edm.provider.NavigationPropertyBinding;
+import org.apache.olingo.commons.api.edm.provider.OnDelete;
+import org.apache.olingo.commons.api.edm.provider.OnDeleteAction;
+import org.apache.olingo.commons.api.edm.provider.Operation;
+import org.apache.olingo.commons.api.edm.provider.Parameter;
+import org.apache.olingo.commons.api.edm.provider.Property;
+import org.apache.olingo.commons.api.edm.provider.PropertyRef;
+import org.apache.olingo.commons.api.edm.provider.ReferentialConstraint;
+import org.apache.olingo.commons.api.edm.provider.ReturnType;
+import org.apache.olingo.commons.api.edm.provider.Schema;
+import org.apache.olingo.commons.api.edm.provider.Singleton;
+import org.apache.olingo.commons.api.edm.provider.Term;
+import org.apache.olingo.commons.api.edm.provider.TypeDefinition;
+
+/**
+ * This class can convert a CSDL document into EDMProvider object
+ */
+public class MetadataParser {
+
+ public EdmProvider buildEdmProvider(Reader csdl) throws XMLStreamException {
+ XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+ XMLEventReader reader = xmlInputFactory.createXMLEventReader(csdl);
+
+ SchemaBasedEdmProvider provider = new SchemaBasedEdmProvider();
+ new ElementReader<SchemaBasedEdmProvider>() {
+ @Override
+ void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
+ String name) throws XMLStreamException {
+ String version = attr(element, "Version");
+ if (version.equals("4.0")) {
+ readDataServicesAndReference(reader, element, provider);
+ }
+ }
+ }.read(reader, null, provider, "Edmx");
+
+ return provider;
+ }
+
+ private void readDataServicesAndReference(XMLEventReader reader, StartElement element,
+ SchemaBasedEdmProvider provider) throws XMLStreamException {
+ new ElementReader<SchemaBasedEdmProvider>() {
+ @Override
+ void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider provider,
+ String name) throws XMLStreamException {
+ if (name.equals("DataServices")) {
+ readSchema(reader, element, provider);
+ } else if (name.equals("Reference")) {
+ readReference(reader, element, provider, "Reference");
+ }
+ }
+ }.read(reader, element, provider, "DataServices", "Reference");
+ }
+
+ private void readReference(XMLEventReader reader, StartElement element,
+ SchemaBasedEdmProvider provider, String name) throws XMLStreamException {
+ new ElementReader<SchemaBasedEdmProvider>() {
+ @Override
+ void build(XMLEventReader reader, StartElement element, SchemaBasedEdmProvider t, String name)
+ throws XMLStreamException {
+ // TODO:
+ }
+ }.read(reader, element, provider, name);
+ }
+
+ private void readSchema(XMLEventReader reader, StartElement element,
+ SchemaBasedEdmProvider provider) throws XMLStreamException {
+
+ Schema schema = new Schema();
+ schema.setComplexTypes(new ArrayList<ComplexType>());
+ schema.setActions(new ArrayList<Action>());
+ schema.setEntityTypes(new ArrayList<EntityType>());
+ schema.setEnumTypes(new ArrayList<EnumType>());
+ schema.setFunctions(new ArrayList<Function>());
+ schema.setTerms(new ArrayList<Term>());
+ schema.setTypeDefinitions(new ArrayList<TypeDefinition>());
+
+ new ElementReader<Schema>() {
+ @Override
+ void build(XMLEventReader reader, StartElement element, Schema schema, String name)
+ throws XMLStreamException {
+ schema.setNamespace(attr(element, "Namespace"));
+ schema.setAlias(attr(element, "Alias"));
+ readSchemaContents(reader, schema);
+ }
+ }.read(reader, element, schema, "Schema");
+ provider.addSchema(schema);
+ }
+
+ private void readSchemaContents(XMLEventReader reader, Schema schema) throws XMLStreamException {
+ new ElementReader<Schema>() {
+ @Override
+ void build(XMLEventReader reader, StartElement element, Schema schema, String name)
+ throws XMLStreamException {
+ if (name.equals("Action")) {
+ readAction(reader, element, schema);
+ } else if (name.equals("Annotations")) {
+ // TODO:
+ } else if (name.equals("Annotation")) {
+ // TODO:
+ } else if (name.equals("ComplexType")) {
+ readComplexType(reader, element, schema);
+ } else if (name.equals("EntityContainer")) {
+ readEntityContainer(reader, element, schema);
+ } else if (name.equals("EntityType")) {
+ readEntityType(reader, element, schema);
+ } else if (name.equals("EnumType")) {
+ readEnumType(reader, element, schema);
+ } else if (name.equals("Function")) {
+ readFunction(reader, element, schema);
+ } else if (name.equals("Term")) {
+ schema.getTerms().add(readTerm(element));
+ } else if (name.equals("TypeDefinition")) {
+ schema.getTypeDefinitions().add(readTypeDefinition(element));
+ }
+ }
+ }.read(reader, null, schema, "Action", "Annotations", "Annotation", "ComplexType",
+ "EntityContainer", "EntityType", "EnumType", "Function", "Term", "TypeDefinition");
+ }
+
+ private void readAction(XMLEventReader reader, StartElement element, Schema schema)
+ throws XMLStreamException {
+
+ Action action = new Action();
+ action.setParameters(new ArrayList<Parameter>());
+ action.setName(attr(element, "Name"));
+ action.setBound(Boolean.parseBoolean(attr(element, "IsBound")));
+ String entitySetPath = attr(element, "EntitySetPath");
+ if (entitySetPath != null) {
+ // TODO: need to parse into binding and path.
+ action.setEntitySetPath(entitySetPath);
+ }
+ readOperationParameters(reader, action);
+ schema.getActions().add(action);
+ }
+
+ private FullQualifiedName readType(StartElement element) {
+ String type = attr(element, "Type");
+ if (type.startsWith("Collection(") && type.endsWith(")")) {
+ return new FullQualifiedName(type.substring(11, type.length() - 1));
+ }
+ return new FullQualifiedName(type);
+ }
+
+ private boolean isCollectionType(StartElement element) {
+ String type = attr(element, "Type");
+ if (type.startsWith("Collection(") && type.endsWith(")")) {
+ return true;
+ }
+ return false;
+ }
+
+ private void readReturnType(StartElement element, Operation operation) {
+ ReturnType returnType = new ReturnType();
+ returnType.setType(readType(element));
+ returnType.setCollection(isCollectionType(element));
+ returnType.setNullable(Boolean.parseBoolean(attr(element, "Nullable")));
+
+ String maxLength = attr(element, "MaxLength");
+ if (maxLength != null) {
+ returnType.setMaxLength(Integer.parseInt(maxLength));
+ }
+ String precision = attr(element, "Precision");
+ if (precision != null) {
+ returnType.setPrecision(Integer.parseInt(precision));
+ }
+ String scale = attr(element, "Scale");
+ if (scale != null) {
+ returnType.setScale(Integer.parseInt(scale));
+ }
+ String srid = attr(element, "SRID");
+ if (srid != null) {
+ // TODO: no olingo support yet.
+ }
+ operation.setReturnType(returnType);
+ }
+
+ private void readParameter(StartElement element, Operation operation) {
+ Parameter parameter = new Parameter();
+ parameter.setName(attr(element, "Name"));
+ parameter.setType(readType(element));
+ parameter.setCollection(isCollectionType(element));
+ parameter.setNullable(Boolean.parseBoolean(attr(element, "Nullable")));
+
+ String maxLength = attr(element, "MaxLength");
+ if (maxLength != null) {
+ parameter.setMaxLength(Integer.parseInt(maxLength));
+ }
+ String precision = attr(element, "Precision");
+ if (precision != null) {
+ parameter.setPrecision(Integer.parseInt(precision));
+ }
+ String scale = attr(element, "Scale");
+ if (scale != null) {
+ parameter.setScale(Integer.parseInt(scale));
+ }
+ String srid = attr(element, "SRID");
+ if (srid != null) {
+ // TODO: no olingo support yet.
+ }
+ operation.getParameters().add(parameter);
+ }
+
+ private TypeDefinition readTypeDefinition(StartElement element) {
+ TypeDefinition td = new TypeDefinition();
+ td.setName(attr(element, "Name"));
+ td.setUnderlyingType(new FullQualifiedName(attr(element, "UnderlyingType")));
+ td.setUnicode(Boolean.parseBoolean(attr(element, "Unicode")));
+
+ String maxLength = attr(element, "MaxLength");
+ if (maxLength != null) {
+ td.setMaxLength(Integer.parseInt(maxLength));
+ }
+ String precision = attr(element, "Precision");
+ if (precision != null) {
+ td.setPrecision(Integer.parseInt(precision));
+ }
+ String scale = attr(element, "Scale");
+ if (scale != null) {
+ td.setScale(Integer.parseInt(scale));
+ }
+ String srid = attr(element, "SRID");
+ if (srid != null) {
+ // TODO: no olingo support yet.
+ }
+ return td;
+ }
+
+ private Term readTerm(StartElement element) {
+ Term term = new Term();
+ term.setName(attr(element, "Name"));
+ term.setType(attr(element, "Type"));
+ if (attr(element, "BaseTerm") != null) {
+ term.setBaseTerm(attr(element, "BaseTerm"));
+ }
+ if (attr(element, "DefaultValue") != null) {
+ term.setDefaultValue(attr(element, "DefaultValue"));
+ }
+ if (attr(element, "AppliesTo") != null) {
+ term.setAppliesTo(Arrays.asList(attr(element, "AppliesTo")));
+ }
+ term.setNullable(Boolean.parseBoolean(attr(element, "Nullable")));
+ String maxLength = attr(element, "MaxLength");
+ if (maxLength != null) {
+ term.setMaxLength(Integer.parseInt(maxLength));
+ }
+ String precision = attr(element, "Precision");
+ if (precision != null) {
+ term.setPrecision(Integer.parseInt(precision));
+ }
+ String scale = attr(element, "Scale");
+ if (scale != null) {
+ term.setScale(Integer.parseInt(scale));
+ }
+ String srid = attr(element, "SRID");
+ if (srid != null) {
+ // TODO: no olingo support yet.
+ }
+ return term;
+ }
+
+ private void readFunction(XMLEventReader reader, StartElement element, Schema schema)
+ throws XMLStreamException {
+ Function function = new Function();
+ function.setParameters(new ArrayList<Parameter>());
+ function.setName(attr(element, "Name"));
+ function.setBound(Boolean.parseBoolean(attr(element, "IsBound")));
+ function.setComposable(Boolean.parseBoolean(attr(element, "IsComposable")));
+ String entitySetPath = attr(element, "EntitySetPath");
+ if (entitySetPath != null) {
+ // TODO: need to parse into binding and path.
+ function.setEntitySetPath(entitySetPath);
+ }
+ readOperationParameters(reader, function);
+ schema.getFunctions().add(function);
+ }
+
+ private void readOperationParameters(XMLEventReader reader, final Operation operation)
+ throws XMLStreamException {
+ new ElementReader<Operation>() {
+ @Override
+ void build(XMLEventReader reader, StartElement element, Operation operation, String name)
+ throws XMLStreamException {
+ if (name.equals("Parameter")) {
+ readParameter(element, operation);
+ } else if (name.equals("ReturnType")) {
+ readReturnType(element, operation);
+ }
+ }
+ }.read(reader, null, operation, "Parameter", "ReturnType");
+ }
+
+ private void readEnumType(XMLEventReader reader, StartElement element, Schema schema)
+ throws XMLStreamException {
+ EnumType type = new EnumType();
+ type.setMembers(new ArrayList<EnumMember>());
+ type.setName(attr(element, "Name"));
+ if (attr(element, "UnderlyingType") != null) {
+ type.setUnderlyingType(new FullQualifiedName(attr(element, "UnderlyingType")));
+ }
+ type.setFlags(Boolean.parseBoolean(attr(element, "IsFlags")));
+
+ readEnumMembers(reader, element, type);
+ schema.getEnumTypes().add(type);
+ }
+
+ private void readEnumMembers(XMLEventReader reader, StartElement element, EnumType type)
+ throws XMLStreamException {
+ new ElementReader<EnumType>() {
+ @Override
+ void build(XMLEventReader reader, StartElement element, EnumType type, String name)
+ throws XMLStreamException {
+ EnumMember member = new EnumMember();
+ member.setName(attr(element, "Name"));
+ member.setValue(attr(element, "Value"));
+ type.getMembers().add(member);
+ }
+ }.read(reader, element, type, "Member");
+ }
+
+ private void readEntityType(XMLEventReader reader, StartElement element, Schema schema)
+ throws XMLStreamException {
+ EntityType entityType = new EntityType();
+ entityType.setProperties(new ArrayList<Property>());
+ entityType.setNavigationProperties(new ArrayList<NavigationProperty>());
+ entityType.setKey(new ArrayList<PropertyRef>());
+ entityType.setName(attr(element, "Name"));
+ if (attr(element, "BaseType") != null) {
+ entityType.setBaseType(new FullQualifiedName(attr(element, "BaseType")));
+ }
+ entityType.setAbstract(Boolean.parseBoolean(attr(element, "Abstract")));
+ entityType.setOpenType(Boolean.parseBoolean(attr(element, "OpenType")));
+ entityType.setHasStream(Boolean.parseBoolean(attr(element, "HasStream")));
+ readEntityProperties(reader, entityType);
+ schema.getEntityTypes().add(entityType);
+ }
+
+ private void readEntityProperties(XMLEventReader reader, EntityType entityType)
+ throws XMLStreamException {
+ new ElementReader<EntityType>() {
+ @Override
+ void build(XMLEventReader reader, StartElement element, EntityType entityType, String name)
+ throws XMLStreamException {
+ if (name.equals("Property")) {
+ entityType.getProperties().add(readProperty(element));
+ } else if (name.equals("NavigationProperty")) {
+ entityType.getNavigationProperties().add(readNavigationProperty(reader, element));
+ } else if (name.equals("Key")) {
+ readKey(reader, element, entityType);
+ }
+ }
+ }.read(reader, null, entityType, "Property", "NavigationProperty", "Key");
+ }
+
+ private void readKey(XMLEventReader reader, StartElement element, EntityType entityType)
+ throws XMLStreamException {
+ new ElementReader<EntityType>() {
+ @Override
+ void build(XMLEventReader reader, StartElement element, EntityType entityType, String name)
+ throws XMLStreamException {
+ PropertyRef ref = new PropertyRef();
+ ref.setName(attr(element, "Name"));
+ ref.setAlias(attr(element, "Alias"));
+ entityType.getKey().add(ref);
+ }
+ }.read(reader, element, entityType, "PropertyRef");
+ }
+
+ private NavigationProperty readNavigationProperty(XMLEventReader reader, StartElement element)
+ throws XMLStreamException {
+ NavigationProperty property = new NavigationProperty();
+ property.setReferentialConstraints(new ArrayList<ReferentialConstraint>());
+
+ property.setName(attr(element, "Name"));
+ property.setType(readType(element));
+ property.setCollection(isCollectionType(element));
+ property.setNullable(Boolean.parseBoolean(attr(element, "Nullable")));
+ property.setPartner(attr(element, "Partner"));
+ property.setContainsTarget(Boolean.parseBoolean(attr(element, "ContainsTarget")));
+
+ new ElementReader<NavigationProperty>() {
+ @Override
+ void build(XMLEventReader reader, StartElement element, NavigationProperty property,
+ String name) throws XMLStreamException {
+ if (name.equals("ReferentialConstraint")) {
+ ReferentialConstraint constraint = new ReferentialConstraint();
+ constraint.setProperty(attr(element, "Property"));
+ constraint.setReferencedProperty(attr(element, "ReferencedProperty"));
+ property.getReferentialConstraints().add(constraint);
+ } else if (name.equals("OnDelete")) {
+ property.setOnDelete(new OnDelete().setAction(OnDeleteAction.valueOf(attr(element, "Action"))));
+ }
+ }
+ }.read(reader, element, property, "ReferentialConstraint", "OnDelete");
+ return property;
+ }
+
+ private String attr(StartElement element, String name) {
+ Attribute attr = element.getAttributeByName(new QName(name));
+ if (attr != null) {
+ return attr.getValue();
+ }
+ return null;
+ }
+
+ private Property readProperty(StartElement element) {
+ Property property = new Property();
+ property.setName(attr(element, "Name"));
+ property.setType(readType(element));
+ property.setCollection(isCollectionType(element));
+ property.setNullable(Boolean.parseBoolean(attr(element, "Nullable") == null ? "true" : attr(
+ element, "Nullable")));
+ property.setUnicode(Boolean.parseBoolean(attr(element, "Unicode")));
+
+ String maxLength = attr(element, "MaxLength");
+ if (maxLength != null) {
+ property.setMaxLength(Integer.parseInt(maxLength));
+ }
+ String precision = attr(element, "Precision");
+ if (precision != null) {
+ property.setPrecision(Integer.parseInt(precision));
+ }
+ String scale = attr(element, "Scale");
+ if (scale != null) {
+ property.setScale(Integer.parseInt(scale));
+ }
+ String srid = attr(element, "SRID");
+ if (srid != null) {
+ // TODO: no olingo support yet.
+ }
+ String defaultValue = attr(element, "DefaultValue");
+ if (defaultValue != null) {
+ property.setDefaultValue(defaultValue);
+ }
+ return property;
+ }
+
+ private void readEntityContainer(XMLEventReader reader, StartElement element, Schema schema)
+ throws XMLStreamException {
+ final EntityContainer container = new EntityContainer();
+ container.setName(attr(element, "Name"));
+ if (attr(element, "Extends") != null) {
+ container.setExtendsContainer(attr(element, "Extends"));
+ }
+ container.setActionImports(new ArrayList<ActionImport>());
+ container.setFunctionImports(new ArrayList<FunctionImport>());
+ container.setEntitySets(new ArrayList<EntitySet>());
+ container.setSingletons(new ArrayList<Singleton>());
+
+ new ElementReader<Schema>() {
+ @Override
+ void build(XMLEventReader reader, StartElement element, Schema schema, String name)
+ throws XMLStreamException {
+ if (name.equals("EntitySet")) {
+ readEntitySet(reader, element, container);
+ } else if (name.equals("Singleton")) {
+ readSingleton(reader, element, container);
+ } else if (name.equals("ActionImport")) {
+ readActionImport(element, container);
+ } else if (name.equals("FunctionImport")) {
+ readFunctionImport(element, container);
+ }
+ }
+
+ private void readFunctionImport(StartElement element, EntityContainer container) {
+ FunctionImport functionImport = new FunctionImport();
+ functionImport.setName(attr(element, "Name"));
+ functionImport.setFunction(new FullQualifiedName(attr(element, "Function")));
+ functionImport.setIncludeInServiceDocument(Boolean.parseBoolean(attr(element,
+ "IncludeInServiceDocument")));
+
+ String entitySet = attr(element, "EntitySet");
+ if (entitySet != null) {
+ functionImport.setEntitySet(entitySet);
+ }
+ container.getFunctionImports().add(functionImport);
+ }
+
+ private void readActionImport(StartElement element, EntityContainer container) {
+ ActionImport actionImport = new ActionImport();
+ actionImport.setName(attr(element, "Name"));
+ actionImport.setAction(new FullQualifiedName(attr(element, "Action")));
+
+ String entitySet = attr(element, "EntitySet");
+ if (entitySet != null) {
+ actionImport.setEntitySet(entitySet);
+ }
+ container.getActionImports().add(actionImport);
+ }
+
+ private void readSingleton(XMLEventReader reader, StartElement element,
+ EntityContainer container) throws XMLStreamException {
+ Singleton singleton = new Singleton();
+ singleton.setNavigationPropertyBindings(new ArrayList<NavigationPropertyBinding>());
+ singleton.setName(attr(element, "Name"));
+ singleton.setType(new FullQualifiedName(attr(element, "Type")));
+ singleton.setNavigationPropertyBindings(new ArrayList<NavigationPropertyBinding>());
+ readNavigationPropertyBindings(reader, element, singleton.getNavigationPropertyBindings());
+ container.getSingletons().add(singleton);
+ }
+
+ private void readEntitySet(XMLEventReader reader, StartElement element,
+ EntityContainer container) throws XMLStreamException {
+ EntitySet entitySet = new EntitySet();
+ entitySet.setName(attr(element, "Name"));
+ entitySet.setType(new FullQualifiedName(attr(element, "EntityType")));
+ entitySet.setIncludeInServiceDocument(Boolean.parseBoolean(attr(element,
+ "IncludeInServiceDocument")));
+ entitySet.setNavigationPropertyBindings(new ArrayList<NavigationPropertyBinding>());
+ readNavigationPropertyBindings(reader, element, entitySet.getNavigationPropertyBindings());
+ container.getEntitySets().add(entitySet);
+ }
+
+ private void readNavigationPropertyBindings(XMLEventReader reader, StartElement element,
+ List<NavigationPropertyBinding> bindings) throws XMLStreamException {
+ new ElementReader<List<NavigationPropertyBinding>>() {
+ @Override
+ void build(XMLEventReader reader, StartElement element,
+ List<NavigationPropertyBinding> bindings, String name) throws XMLStreamException {
+ NavigationPropertyBinding binding = new NavigationPropertyBinding();
+ binding.setPath(attr(element, "Path"));
+ binding.setTarget(attr(element, "Target"));
+ bindings.add(binding);
+ }
+
+ }.read(reader, element, bindings, "NavigationPropertyBinding");
+ ;
+ }
+ }.read(reader, element, schema, "EntitySet", "Singleton", "ActionImport", "FunctionImport");
+ schema.setEntityContainer(container);
+ }
+
+ private void readComplexType(XMLEventReader reader, StartElement element, Schema schema)
+ throws XMLStreamException {
+ ComplexType complexType = new ComplexType();
+ complexType.setProperties(new ArrayList<Property>());
+ complexType.setNavigationProperties(new ArrayList<NavigationProperty>());
+ complexType.setName(attr(element, "Name"));
+ if (attr(element, "BaseType") != null) {
+ complexType.setBaseType(new FullQualifiedName(attr(element, "BaseType")));
+ }
+ complexType.setAbstract(Boolean.parseBoolean(attr(element, "Abstract")));
+ complexType.setOpenType(Boolean.parseBoolean(attr(element, "OpenType")));
+ readProperties(reader, complexType);
+
+ schema.getComplexTypes().add(complexType);
+ }
+
+ private void readProperties(XMLEventReader reader, ComplexType complexType)
+ throws XMLStreamException {
+ new ElementReader<ComplexType>() {
+ @Override
+ void build(XMLEventReader reader, StartElement element, ComplexType complexType, String name)
+ throws XMLStreamException {
+ if (name.equals("Property")) {
+ complexType.getProperties().add(readProperty(element));
+ } else if (name.equals("NavigationProperty")) {
+ complexType.getNavigationProperties().add(readNavigationProperty(reader, element));
+ }
+ }
+ }.read(reader, null, complexType, "Property", "NavigationProperty");
+ }
+
+ abstract class ElementReader<T> {
+ void read(XMLEventReader reader, StartElement element, T t, String... names)
+ throws XMLStreamException {
+ while (reader.hasNext()) {
+ XMLEvent event = reader.peek();
+
+ event = skipAnnotations(reader, event);
+
+ if (!event.isStartElement() && !event.isEndElement()) {
+ reader.nextEvent();
+ continue;
+ }
+
+ boolean hit = false;
+
+ for (int i = 0; i < names.length; i++) {
+ if (event.isStartElement()) {
+ element = event.asStartElement();
+ if (element.getName().getLocalPart().equals(names[i])) {
+ reader.nextEvent(); // advance cursor
+ // System.out.println("reading = "+names[i]);
+ build(reader, element, t, names[i]);
+ hit = true;
+ }
+ }
+ if (event.isEndElement()) {
+ EndElement e = event.asEndElement();
+ if (e.getName().getLocalPart().equals(names[i])) {
+ reader.nextEvent(); // advance cursor
+ // System.out.println("done reading = "+names[i]);
+ hit = true;
+ }
+ }
+ }
+ if (!hit) {
+ break;
+ }
+ }
+ }
+
+ private XMLEvent skipAnnotations(XMLEventReader reader, XMLEvent event)
+ throws XMLStreamException {
+ boolean skip = false;
+
+ while (reader.hasNext()) {
+ if (event.isStartElement()) {
+ StartElement element = event.asStartElement();
+ if (element.getName().getLocalPart().equals("Annotation")) {
+ skip = true;
+ }
+ }
+ if (event.isEndElement()) {
+ EndElement element = event.asEndElement();
+ if (element.getName().getLocalPart().equals("Annotation")) {
+ return reader.peek();
+ }
+ }
+ if (skip) {
+ event = reader.nextEvent();
+ } else {
+ return event;
+ }
+ }
+ return event;
+ }
+
+ abstract void build(XMLEventReader reader, StartElement element, T t, String name)
+ throws XMLStreamException;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4HttpHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4HttpHandler.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4HttpHandler.java
new file mode 100644
index 0000000..ddb8e6b
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4HttpHandler.java
@@ -0,0 +1,123 @@
+/*
+ * 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;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
+import org.apache.olingo.commons.api.http.HttpHeader;
+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.ODataTranslatedException;
+import org.apache.olingo.server.api.ServiceMetadata;
+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.legacy.ProcessorServiceHandler;
+
+public class OData4HttpHandler extends ODataHttpHandlerImpl {
+ private ServiceHandler handler;
+ private final ServiceMetadata serviceMetadata;
+ private final OData odata;
+ private CustomContentTypeSupport customContentTypeSupport;
+
+
+ public OData4HttpHandler(OData odata, ServiceMetadata serviceMetadata) {
+ super(odata, serviceMetadata);
+ this.odata = odata;
+ this.serviceMetadata = serviceMetadata;
+ // this is support old interfaces
+ this.handler = new ProcessorServiceHandler();
+ this.handler.init(odata, serviceMetadata);
+ }
+
+ @Override
+ public void process(final HttpServletRequest httpRequest, final HttpServletResponse httpResponse) {
+ ODataRequest request = null;
+ ODataResponse response = new ODataResponse();
+
+ try {
+ request = createODataRequest(httpRequest, 0);
+ validateODataVersion(request, response);
+
+ ServiceDispatcher dispatcher = new ServiceDispatcher(this.odata, this.serviceMetadata,
+ handler, this.customContentTypeSupport);
+ dispatcher.execute(request, response);
+
+ } catch (Exception e) {
+ ErrorHandler handler = new ErrorHandler(this.odata, this.serviceMetadata,
+ this.customContentTypeSupport);
+ handler.handleException(e, request, response);
+ }
+ convertToHttp(httpResponse, response);
+ }
+
+
+ ODataRequest createODataRequest(final HttpServletRequest httpRequest, final int split)
+ throws ODataTranslatedException {
+ try {
+ ODataRequest odRequest = new ODataRequest();
+
+ odRequest.setBody(httpRequest.getInputStream());
+ extractHeaders(odRequest, httpRequest);
+ extractMethod(odRequest, httpRequest);
+ extractUri(odRequest, httpRequest, split);
+
+ return odRequest;
+ } catch (final IOException e) {
+ throw new SerializerException(
+ "An I/O exception occurred.", e, SerializerException.MessageKeys.IO_EXCEPTION); //$NON-NLS-1$
+ }
+ }
+
+ void validateODataVersion(final ODataRequest request, final ODataResponse response)
+ throws ODataHandlerException {
+ final String maxVersion = request.getHeader(HttpHeader.ODATA_MAX_VERSION);
+ response.setHeader(HttpHeader.ODATA_VERSION, ODataServiceVersion.V40.toString());
+
+ if (maxVersion != null) {
+ if (ODataServiceVersion.isBiggerThan(ODataServiceVersion.V40.toString(), maxVersion)) {
+ throw new ODataHandlerException("ODataVersion not supported: " + maxVersion, //$NON-NLS-1$
+ ODataHandlerException.MessageKeys.ODATA_VERSION_NOT_SUPPORTED, maxVersion);
+ }
+ }
+ }
+
+ @Override
+ public void register(final Processor processor) {
+
+ if (processor instanceof ServiceHandler) {
+ this.handler = (ServiceHandler) processor;
+ this.handler.init(this.odata, this.serviceMetadata);
+ }
+
+ if (this.handler instanceof ProcessorServiceHandler) {
+ ((ProcessorServiceHandler)this.handler).register(processor);
+ }
+ }
+
+ @Override
+ public void register(final CustomContentTypeSupport customContentTypeSupport) {
+ this.customContentTypeSupport = customContentTypeSupport;
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4Impl.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4Impl.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4Impl.java
new file mode 100644
index 0000000..bde9c96
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/OData4Impl.java
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+import org.apache.olingo.commons.api.ODataRuntimeException;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ODataHttpHandler;
+import org.apache.olingo.server.api.ServiceMetadata;
+
+public class OData4Impl extends ODataImpl {
+
+ public static OData newInstance() {
+ try {
+ final Class<?> clazz = Class.forName(OData4Impl.class.getName());
+ final Object object = clazz.newInstance();
+ return (OData) object;
+ } catch (final Exception e) {
+ throw new ODataRuntimeException(e);
+ }
+ }
+
+ private OData4Impl() {
+ }
+
+ @Override
+ public ODataHttpHandler createHandler(final ServiceMetadata edm) {
+ return new OData4HttpHandler(this, edm);
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8668b097/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/RequestURLHierarchyVisitor.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/RequestURLHierarchyVisitor.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/RequestURLHierarchyVisitor.java
new file mode 100644
index 0000000..ee00638
--- /dev/null
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/RequestURLHierarchyVisitor.java
@@ -0,0 +1,333 @@
+/*
+ * 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;
+
+import java.util.List;
+
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.api.uri.UriInfoAll;
+import org.apache.olingo.server.api.uri.UriInfoBatch;
+import org.apache.olingo.server.api.uri.UriInfoCrossjoin;
+import org.apache.olingo.server.api.uri.UriInfoEntityId;
+import org.apache.olingo.server.api.uri.UriInfoKind;
+import org.apache.olingo.server.api.uri.UriInfoMetadata;
+import org.apache.olingo.server.api.uri.UriInfoResource;
+import org.apache.olingo.server.api.uri.UriInfoService;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceAction;
+import org.apache.olingo.server.api.uri.UriResourceComplexProperty;
+import org.apache.olingo.server.api.uri.UriResourceCount;
+import org.apache.olingo.server.api.uri.UriResourceEntitySet;
+import org.apache.olingo.server.api.uri.UriResourceFunction;
+import org.apache.olingo.server.api.uri.UriResourceIt;
+import org.apache.olingo.server.api.uri.UriResourceLambdaAll;
+import org.apache.olingo.server.api.uri.UriResourceLambdaAny;
+import org.apache.olingo.server.api.uri.UriResourceLambdaVariable;
+import org.apache.olingo.server.api.uri.UriResourceNavigation;
+import org.apache.olingo.server.api.uri.UriResourcePrimitiveProperty;
+import org.apache.olingo.server.api.uri.UriResourceRef;
+import org.apache.olingo.server.api.uri.UriResourceRoot;
+import org.apache.olingo.server.api.uri.UriResourceSingleton;
+import org.apache.olingo.server.api.uri.UriResourceValue;
+import org.apache.olingo.server.api.uri.queryoption.CountOption;
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
+import org.apache.olingo.server.api.uri.queryoption.FilterOption;
+import org.apache.olingo.server.api.uri.queryoption.FormatOption;
+import org.apache.olingo.server.api.uri.queryoption.IdOption;
+import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
+import org.apache.olingo.server.api.uri.queryoption.SearchOption;
+import org.apache.olingo.server.api.uri.queryoption.SelectOption;
+import org.apache.olingo.server.api.uri.queryoption.SkipOption;
+import org.apache.olingo.server.api.uri.queryoption.SkipTokenOption;
+import org.apache.olingo.server.api.uri.queryoption.TopOption;
+
+public class RequestURLHierarchyVisitor implements RequestURLVisitor {
+
+ private UriInfo uriInfo;
+
+ public UriInfo getUriInfo() {
+ return this.uriInfo;
+ }
+
+ @Override
+ public void visit(UriInfo info) {
+ this.uriInfo = info;
+
+ UriInfoKind kind = info.getKind();
+ switch (kind) {
+ case all:
+ visit(info.asUriInfoAll());
+ break;
+ case batch:
+ visit(info.asUriInfoBatch());
+ break;
+ case crossjoin:
+ visit(info.asUriInfoCrossjoin());
+ break;
+ case entityId:
+ visit(info.asUriInfoEntityId());
+ break;
+ case metadata:
+ visit(info.asUriInfoMetadata());
+ break;
+ case resource:
+ visit(info.asUriInfoResource());
+ break;
+ case service:
+ visit(info.asUriInfoService());
+ break;
+ }
+ }
+
+ @Override
+ public void visit(UriInfoService info) {
+ }
+
+ @Override
+ public void visit(UriInfoAll info) {
+ }
+
+ @Override
+ public void visit(UriInfoBatch info) {
+ }
+
+ @Override
+ public void visit(UriInfoCrossjoin info) {
+ }
+
+ @Override
+ public void visit(UriInfoEntityId info) {
+ visit(info.getSelectOption());
+
+ if (info.getExpandOption() != null) {
+ visit(info.getExpandOption());
+ }
+ if (info.getFormatOption() != null) {
+ visit(info.getFormatOption());
+ }
+ if (info.getIdOption() != null) {
+ visit(info.getIdOption(), info.getEntityTypeCast());
+ }
+ }
+
+ @Override
+ public void visit(UriInfoMetadata info) {
+ }
+
+ @Override
+ public void visit(UriInfoResource info) {
+ List<UriResource> parts = info.getUriResourceParts();
+ for (UriResource resource : parts) {
+ switch (resource.getKind()) {
+ case action:
+ visit((UriResourceAction) resource);
+ break;
+ case complexProperty:
+ visit((UriResourceComplexProperty) resource);
+ break;
+ case count:
+ visit((UriResourceCount) resource);
+ break;
+ case entitySet:
+ visit((UriResourceEntitySet) resource);
+ break;
+ case function:
+ visit((UriResourceFunction) resource);
+ break;
+ case it:
+ visit((UriResourceIt) resource);
+ break;
+ case lambdaAll:
+ visit((UriResourceLambdaAll) resource);
+ break;
+ case lambdaAny:
+ visit((UriResourceLambdaAny) resource);
+ break;
+ case lambdaVariable:
+ visit((UriResourceLambdaVariable) resource);
+ break;
+ case navigationProperty:
+ visit((UriResourceNavigation) resource);
+ break;
+ case ref:
+ visit((UriResourceRef) resource);
+ break;
+ case root:
+ visit((UriResourceRoot) resource);
+ break;
+ case primitiveProperty:
+ visit((UriResourcePrimitiveProperty) resource);
+ break;
+ case singleton:
+ visit((UriResourceSingleton) resource);
+ break;
+ case value:
+ visit((UriResourceValue) resource);
+ break;
+ }
+ }
+
+ // http://docs.oasis-open.org/odata/odata/v4.0/os/part1-protocol/odata-v4.0-os-part1-protocol.html#_Toc372793682
+ if (info.getSearchOption() != null) {
+ visit(info.getSearchOption());
+ }
+
+ if (info.getFilterOption() != null) {
+ visit(info.getFilterOption());
+ }
+
+ if (info.getCountOption() != null) {
+ visit(info.getCountOption());
+ }
+
+ visit(info.getOrderByOption());
+
+ if (info.getSkipOption() != null) {
+ visit(info.getSkipOption());
+ }
+
+ if (info.getTopOption() != null) {
+ visit(info.getTopOption());
+ }
+
+ if (info.getExpandOption() != null) {
+ visit(info.getExpandOption());
+ }
+
+ visit(info.getSelectOption());
+
+ if (info.getFormatOption() != null) {
+ visit(info.getFormatOption());
+ }
+
+ if (info.getIdOption() != null) {
+ visit(info.getIdOption(), null);
+ }
+
+ if (info.getSkipTokenOption() != null) {
+ visit(info.getSkipTokenOption());
+ }
+
+ }
+
+ @Override
+ public void visit(ExpandOption option) {
+ }
+
+ @Override
+ public void visit(FilterOption info) {
+ }
+
+ @Override
+ public void visit(FormatOption info) {
+ }
+
+ @Override
+ public void visit(IdOption info, EdmEntityType type) {
+ }
+
+ @Override
+ public void visit(CountOption info) {
+ }
+
+ @Override
+ public void visit(OrderByOption option) {
+ }
+
+ @Override
+ public void visit(SearchOption option) {
+ }
+
+ @Override
+ public void visit(SelectOption option) {
+ }
+
+ @Override
+ public void visit(SkipOption option) {
+ }
+
+ @Override
+ public void visit(SkipTokenOption option) {
+ }
+
+ @Override
+ public void visit(TopOption option) {
+ }
+
+ @Override
+ public void visit(UriResourceCount option) {
+ }
+
+ @Override
+ public void visit(UriResourceRef info) {
+ }
+
+ @Override
+ public void visit(UriResourceRoot info) {
+ }
+
+ @Override
+ public void visit(UriResourceValue info) {
+ }
+
+ @Override
+ public void visit(UriResourceAction info) {
+ }
+
+ @Override
+ public void visit(UriResourceEntitySet info) {
+ }
+
+ @Override
+ public void visit(UriResourceFunction info) {
+ }
+
+ @Override
+ public void visit(UriResourceIt info) {
+ }
+
+ @Override
+ public void visit(UriResourceLambdaAll info) {
+ }
+
+ @Override
+ public void visit(UriResourceLambdaAny info) {
+ }
+
+ @Override
+ public void visit(UriResourceLambdaVariable info) {
+ }
+
+ @Override
+ public void visit(UriResourceNavigation info) {
+ }
+
+ @Override
+ public void visit(UriResourceSingleton info) {
+ }
+
+ @Override
+ public void visit(UriResourceComplexProperty info) {
+ }
+
+ @Override
+ public void visit(UriResourcePrimitiveProperty info) {
+ }
+}