You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by sk...@apache.org on 2014/05/19 15:28:06 UTC

[17/50] [abbrv] git commit: [OLINGO-266] TDD for metadata & service doc

[OLINGO-266] TDD for metadata & service doc


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/7f5a119e
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/7f5a119e
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/7f5a119e

Branch: refs/heads/master
Commit: 7f5a119e42e6e78c499251d25a6843d12a57ef65
Parents: 0c32f1a
Author: Stephan Klevenz <st...@sap.com>
Authored: Fri May 16 15:31:51 2014 +0200
Committer: Stephan Klevenz <st...@sap.com>
Committed: Mon May 19 14:27:05 2014 +0200

----------------------------------------------------------------------
 .../org/apache/olingo/server/api/OData.java     | 55 ++++++++++++++
 .../apache/olingo/server/api/ODataServer.java   | 55 --------------
 .../apache/olingo/server/core/ODataHandler.java | 50 ++++++++++---
 .../server/core/ODataHttpHandlerImpl.java       | 78 +++++++++++++++-----
 .../apache/olingo/server/core/ODataImpl.java    | 61 +++++++++++++++
 .../apache/olingo/server/core/ODataRequest.java |  9 +++
 .../olingo/server/core/ODataServerImpl.java     | 61 ---------------
 .../json/ServiceDocumentJsonSerializer.java     | 13 +++-
 .../server/core/ODataHttpHandlerImplTest.java   | 78 +++++++++++++++++++-
 .../olingo/server/tecsvc/TechnicalServlet.java  | 19 ++---
 .../olingo/server/core/ODataHandlerTest.java    | 17 +++--
 .../serializer/json/ServiceDocumentTest.java    |  4 +-
 .../serializer/xml/MetadataDocumentTest.java    | 10 +--
 13 files changed, 335 insertions(+), 175 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7f5a119e/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java
new file mode 100644
index 0000000..9e1e8fc
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.api;
+
+import org.apache.olingo.commons.api.ODataRuntimeException;
+import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.server.api.edm.provider.EdmProvider;
+import org.apache.olingo.server.api.serializer.ODataFormat;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+
+public abstract class OData {
+
+  private static final String IMPLEMENTATION = "org.apache.olingo.server.core.ODataImpl";
+
+  public static OData newInstance() {
+    try {
+      final Class<?> clazz = Class.forName(OData.IMPLEMENTATION);
+
+      /*
+       * We explicitly do not use the singleton pattern to keep the server state free
+       * and avoid class loading issues also during hot deployment.
+       */
+      final Object object = clazz.newInstance();
+
+      return (OData) object;
+
+    } catch (final Exception e) {
+      // TODO: Change to ODataRuntimeExcfeption
+      throw new ODataRuntimeException(e);
+    }
+  }
+
+  public abstract ODataSerializer createSerializer(ODataFormat format);
+
+  public abstract ODataHttpHandler createHandler(Edm edm);
+
+  public abstract Edm createEdm(EdmProvider edmProvider);
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7f5a119e/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataServer.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataServer.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataServer.java
deleted file mode 100644
index 48aa5a7..0000000
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataServer.java
+++ /dev/null
@@ -1,55 +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.api;
-
-import org.apache.olingo.commons.api.ODataRuntimeException;
-import org.apache.olingo.commons.api.edm.Edm;
-import org.apache.olingo.server.api.edm.provider.EdmProvider;
-import org.apache.olingo.server.api.serializer.ODataFormat;
-import org.apache.olingo.server.api.serializer.ODataSerializer;
-
-public abstract class ODataServer {
-
-  private static final String IMPLEMENTATION = "org.apache.olingo.server.core.ODataServerImpl";
-
-  public static ODataServer newInstance() {
-    try {
-      final Class<?> clazz = Class.forName(ODataServer.IMPLEMENTATION);
-
-      /*
-       * We explicitly do not use the singleton pattern to keep the server state free
-       * and avoid class loading issues also during hot deployment.
-       */
-      final Object object = clazz.newInstance();
-
-      return (ODataServer) object;
-
-    } catch (final Exception e) {
-      // TODO: Change to ODataRuntimeExcfeption
-      throw new ODataRuntimeException(e);
-    }
-  }
-
-  public abstract ODataSerializer createSerializer(ODataFormat format);
-
-  public abstract ODataHttpHandler createHandler(Edm edm);
-
-  public abstract Edm createEdm(EdmProvider edmProvider);
-
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7f5a119e/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
index da6baf7..d9e1e1f 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
@@ -20,32 +20,60 @@ package org.apache.olingo.server.core;
 
 import java.io.InputStream;
 
+import org.apache.olingo.commons.api.ODataRuntimeException;
 import org.apache.olingo.commons.api.edm.Edm;
-import org.apache.olingo.server.api.ODataServer;
+import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.serializer.ODataFormat;
 import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.core.uri.parser.Parser;
 
 public class ODataHandler {
 
-  private final ODataServer server;
+  private final OData server;
   private final Edm edm;
 
-  public ODataHandler(final ODataServer server, final Edm edm) {
+  public ODataHandler(final OData server, final Edm edm) {
     this.server = server;
     this.edm = edm;
   }
 
   public ODataResponse process(final ODataRequest odRequest) {
-    ODataResponse response = new ODataResponse();
+    try {
+      ODataResponse response = new ODataResponse();
 
-    ODataSerializer serializer = server.createSerializer(ODataFormat.JSON);
-    InputStream responseEntity = serializer.serviceDocument(edm, "http://root");
+      Parser parser = new Parser();
+      String odUri =
+          odRequest.getRawODataPath() + (odRequest.getRawQueryPath() == null ? "" : "?" + odRequest.getRawQueryPath());
+      UriInfo uriInfo = parser.parseUri(odUri, edm);
 
-    response.setStatusCode(200);
-    response.setHeader("Content-Type", "application/json");
-    response.setContent(responseEntity);
+      ODataSerializer serializer;
+      InputStream responseEntity;
+      switch (uriInfo.getKind()) {
+      case metadata:
+        serializer = server.createSerializer(ODataFormat.XML);
+        responseEntity = serializer.metadataDocument(edm);
+        
+        response.setStatusCode(200);
+        response.setHeader("Content-Type", "application/xml");
+        response.setContent(responseEntity);
+        break;
+      case service:
+        serializer = server.createSerializer(ODataFormat.JSON);
+        responseEntity = serializer.serviceDocument(edm, odRequest.getRawBaseUri());
+        
+        response.setStatusCode(200);
+        response.setHeader("Content-Type", "application/json");
+        response.setContent(responseEntity);
+        break;
+      default:
+        throw new ODataRuntimeException("not implemented");
+      }
 
-    return response;
+      return response;
+    } catch (Exception e) {
+      // TODO OData error message handling
+      throw new RuntimeException(e);
+    }
   }
-
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7f5a119e/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
index 2efba90..09983b1 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
@@ -21,7 +21,6 @@ package org.apache.olingo.server.core;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.List;
@@ -35,7 +34,7 @@ import org.apache.olingo.commons.api.ODataRuntimeException;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.http.HttpMethod;
 import org.apache.olingo.server.api.ODataHttpHandler;
-import org.apache.olingo.server.api.ODataServer;
+import org.apache.olingo.server.api.OData;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -44,23 +43,24 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
   private static final Logger LOG = LoggerFactory.getLogger(ODataHttpHandlerImpl.class);
 
   private Edm edm;
-  private ODataServer server;
+  private OData server;
 
-  public ODataHttpHandlerImpl(final ODataServer server, final Edm edm) {
+  public ODataHttpHandlerImpl(final OData server, final Edm edm) {
     this.edm = edm;
     this.server = server;
   }
 
   @Override
   public void process(final HttpServletRequest request, final HttpServletResponse response) {
-    ODataRequest odRequest = createODataRequest(request);
+    ODataRequest odRequest = createODataRequest(request, 0);
 
     ODataHandler handler = new ODataHandler(server, edm);
     ODataResponse odResponse = handler.process(odRequest);
+
     convertToHttp(response, odResponse);
   }
 
-  private void convertToHttp(final HttpServletResponse response, final ODataResponse odResponse) {
+  static void convertToHttp(final HttpServletResponse response, final ODataResponse odResponse) {
     response.setStatus(odResponse.getStatusCode());
 
     for (Entry<String, String> entry : odResponse.getHeaders().entrySet()) {
@@ -92,24 +92,51 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
     }
   }
 
-  private ODataRequest createODataRequest(final HttpServletRequest httpRequest) {
+  private ODataRequest createODataRequest(final HttpServletRequest httpRequest, int split) {
     try {
       ODataRequest odRequest = new ODataRequest();
 
       odRequest.setBody(httpRequest.getInputStream());
-      odRequest.setHeaders(extractHeaders(httpRequest));
-      odRequest.setMethod(HttpMethod.valueOf(httpRequest.getMethod()));
-
-      // request uri string
-      fillRequestUri(odRequest, httpRequest, 0);
+      extractHeaders(odRequest, httpRequest);
+      extractMethod(odRequest, httpRequest);
+      extractUri(odRequest, httpRequest, split);
 
       return odRequest;
-    } catch (Exception e) {
+    } catch (IOException e) {
       throw new ODataRuntimeException(e);
     }
   }
 
-  static void fillRequestUri(ODataRequest odRequest, final HttpServletRequest httpRequest, int split) {
+  static void extractMethod(ODataRequest odRequest, HttpServletRequest httpRequest) {
+    try {
+
+      HttpMethod httpRequestMethod = HttpMethod.valueOf(httpRequest.getMethod());
+
+      if (httpRequestMethod == HttpMethod.POST) {
+        String xHttpMethod = httpRequest.getHeader("X-HTTP-Method");
+        String xHttpMethodOverride = httpRequest.getHeader("X-HTTP-Method-Override");
+
+        if (xHttpMethod == null && xHttpMethodOverride == null) {
+          odRequest.setMethod(httpRequestMethod);
+        } else if (xHttpMethod == null && xHttpMethodOverride != null) {
+          odRequest.setMethod(HttpMethod.valueOf(xHttpMethodOverride));
+        } else if (xHttpMethod != null && xHttpMethodOverride == null) {
+          odRequest.setMethod(HttpMethod.valueOf(xHttpMethod));
+        } else {
+          if (!xHttpMethod.equalsIgnoreCase(xHttpMethodOverride)) {
+            throw new ODataRuntimeException("!!! HTTP 400 !!! Ambiguous X-HTTP-Methods!");
+          }
+          odRequest.setMethod(HttpMethod.valueOf(xHttpMethod));
+        }
+      } else {
+        odRequest.setMethod(httpRequestMethod);
+      }
+    } catch (IllegalArgumentException e) {
+      throw new ODataRuntimeException("!!! HTTP 501 !!!");
+    }
+  }
+
+  static void extractUri(ODataRequest odRequest, final HttpServletRequest httpRequest, int split) {
 
     String rawRequestUri = httpRequest.getRequestURL().toString();
 
@@ -128,9 +155,21 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
       rawODataPath = httpRequest.getRequestURI();
     }
 
-    for (int i = 0; i < split; i++) {
-      int e = rawODataPath.indexOf("/", 1);
-      rawODataPath = rawODataPath.substring(e);
+    String rawServiceResolutionUri;
+    if (split > 0) {
+      rawServiceResolutionUri = rawODataPath;
+      for (int i = 0; i < split; i++) {
+        int e = rawODataPath.indexOf("/", 1);
+        if (-1 == e) {
+          rawODataPath = "";
+        } else {
+          rawODataPath = rawODataPath.substring(e);
+        }
+      }
+      int end = rawServiceResolutionUri.length() - rawODataPath.length();
+      rawServiceResolutionUri = rawServiceResolutionUri.substring(0, end);
+    } else {
+      rawServiceResolutionUri = null;
     }
 
     String rawBaseUri = rawRequestUri.substring(0, rawRequestUri.length() - rawODataPath.length());
@@ -140,9 +179,10 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
         + (httpRequest.getQueryString() == null ? "" : "?" + httpRequest.getQueryString()));
     odRequest.setRawODataPath(rawODataPath);
     odRequest.setRawBaseUri(rawBaseUri);
+    odRequest.setRawServiceResolutionUri(rawServiceResolutionUri);
   }
 
-  private Map<String, List<String>> extractHeaders(final HttpServletRequest req) {
+  private void extractHeaders(ODataRequest odRequest, final HttpServletRequest req) {
     Map<String, List<String>> requestHeaders = new HashMap<String, List<String>>();
 
     for (Enumeration<?> headerNames = req.getHeaderNames(); headerNames.hasMoreElements();) {
@@ -158,6 +198,6 @@ public class ODataHttpHandlerImpl implements ODataHttpHandler {
         requestHeaders.put(headerName, headerValues);
       }
     }
-    return requestHeaders;
+    odRequest.setHeaders(requestHeaders);
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7f5a119e/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
new file mode 100644
index 0000000..8b18e87
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
@@ -0,0 +1,61 @@
+/*
+ * 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.commons.api.edm.Edm;
+import org.apache.olingo.server.api.ODataHttpHandler;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.edm.provider.EdmProvider;
+import org.apache.olingo.server.api.serializer.ODataFormat;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.core.edm.provider.EdmProviderImpl;
+import org.apache.olingo.server.core.serializer.ODataJsonSerializer;
+import org.apache.olingo.server.core.serializer.ODataXmlSerializerImpl;
+
+public class ODataImpl extends OData {
+
+  @Override
+  public ODataSerializer createSerializer(final ODataFormat format) {
+    ODataSerializer serializer;
+    switch (format) {
+    case JSON:
+      serializer = new ODataJsonSerializer();
+      break;
+    case XML:
+      serializer = new ODataXmlSerializerImpl();
+      break;
+    default:
+      throw new ODataRuntimeException("Unsupported format: " + format);
+    }
+
+    return serializer;
+  }
+
+  @Override
+  public ODataHttpHandler createHandler(final Edm edm) {
+    return new ODataHttpHandlerImpl(this, edm);
+  }
+
+  @Override
+  public Edm createEdm(final EdmProvider edmProvider) {
+    return new EdmProviderImpl(edmProvider);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7f5a119e/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataRequest.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataRequest.java
index ce2f4b3..2a943e4 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataRequest.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataRequest.java
@@ -34,6 +34,7 @@ public class ODataRequest {
   private String rawRequestUri;
   private String rawODataPath;
   private String rawBaseUri;
+  private String rawServiceResolutionUri;
 
   public HttpMethod getMethod() {
     return method;
@@ -91,4 +92,12 @@ public class ODataRequest {
   public void setRawBaseUri(String rawBaseUri) {
     this.rawBaseUri = rawBaseUri;
   }
+
+  public String getRawServiceResolutionUri() {
+    return rawServiceResolutionUri;
+  }
+
+  public void setRawServiceResolutionUri(String rawServiceResolutionUri) {
+    this.rawServiceResolutionUri = rawServiceResolutionUri;
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7f5a119e/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataServerImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataServerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataServerImpl.java
deleted file mode 100644
index 05bc8ed..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataServerImpl.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.olingo.server.core;
-
-import org.apache.olingo.commons.api.ODataRuntimeException;
-import org.apache.olingo.commons.api.edm.Edm;
-import org.apache.olingo.server.api.ODataHttpHandler;
-import org.apache.olingo.server.api.ODataServer;
-import org.apache.olingo.server.api.edm.provider.EdmProvider;
-import org.apache.olingo.server.api.serializer.ODataFormat;
-import org.apache.olingo.server.api.serializer.ODataSerializer;
-import org.apache.olingo.server.core.edm.provider.EdmProviderImpl;
-import org.apache.olingo.server.core.serializer.ODataJsonSerializer;
-import org.apache.olingo.server.core.serializer.ODataXmlSerializerImpl;
-
-public class ODataServerImpl extends ODataServer {
-
-  @Override
-  public ODataSerializer createSerializer(final ODataFormat format) {
-    ODataSerializer serializer;
-    switch (format) {
-    case JSON:
-      serializer = new ODataJsonSerializer();
-      break;
-    case XML:
-      serializer = new ODataXmlSerializerImpl();
-      break;
-    default:
-      throw new ODataRuntimeException("Unsupported format: " + format);
-    }
-
-    return serializer;
-  }
-
-  @Override
-  public ODataHttpHandler createHandler(final Edm edm) {
-    return new ODataHttpHandlerImpl(this, edm);
-  }
-
-  @Override
-  public Edm createEdm(final EdmProvider edmProvider) {
-    return new EdmProviderImpl(edmProvider);
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7f5a119e/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentJsonSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentJsonSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentJsonSerializer.java
index 827824b..38d8873 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentJsonSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentJsonSerializer.java
@@ -52,7 +52,18 @@ public class ServiceDocumentJsonSerializer {
   public void writeServiceDocument(final JsonGenerator gen) throws JsonGenerationException, IOException {
     gen.writeStartObject();
 
-    Object metadataUri = serviceRoot + "/" + METADATA;
+    Object metadataUri;
+
+    if (serviceRoot == null) {
+      metadataUri = METADATA;
+    } else {
+      if (serviceRoot.endsWith("/")) {
+        metadataUri = serviceRoot + METADATA;
+      } else {
+        metadataUri = serviceRoot + "/" + METADATA;
+      }
+    }
+    
     gen.writeObjectField(ODATA_CONTEXT, metadataUri);
     gen.writeArrayFieldStart(VALUE);
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7f5a119e/lib/server-core/src/test/java/org/apache/olingo/server/core/ODataHttpHandlerImplTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/ODataHttpHandlerImplTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/ODataHttpHandlerImplTest.java
index 0d82a0c..2bc24e1 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/ODataHttpHandlerImplTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/ODataHttpHandlerImplTest.java
@@ -19,11 +19,14 @@
 package org.apache.olingo.server.core;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import javax.servlet.http.HttpServletRequest;
 
+import org.apache.olingo.commons.api.ODataRuntimeException;
+import org.apache.olingo.commons.api.http.HttpMethod;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,34 +36,103 @@ public class ODataHttpHandlerImplTest {
   private final Logger LOG = LoggerFactory.getLogger(ODataHttpHandlerImplTest.class);
 
   @Test
-  public void fillRequestGeneric() {
+  public void extractMethod() {
+    String[][] mm = {
+        { "GET", null, null, "GET" },
+        { "GET", "xxx", "yyy", "GET" },
+        { "PUT", "xxx", "yyy", "PUT" },
+        { "MERGE", "xxx", "yyy", "MERGE" },
+        { "DELETE", "xxx", "yyy", "DELETE" },
+        { "PATCH", "xxx", "yyy", "PATCH" },
+
+        { "POST", null, null, "POST" },
+        { "POST", null, "GET", "GET" },
+        { "POST", null, "PATCH", "PATCH" },
+
+        { "POST", "GET", null, "GET" },
+        { "POST", "MERGE", null, "MERGE" },
+
+        { "POST", "GET", "GET", "GET" },
+    };
+
+    for (String[] m : mm) {
+
+      HttpServletRequest hr = mock(HttpServletRequest.class);
+
+      when(hr.getMethod()).thenReturn(m[0]);
+      when(hr.getHeader("X-HTTP-Method")).thenReturn(m[1]);
+      when(hr.getHeader("X-HTTP-Method-Override")).thenReturn(m[2]);
+
+      ODataRequest odr = new ODataRequest();
+      ODataHttpHandlerImpl.extractMethod(odr, hr);
+
+      assertEquals(HttpMethod.valueOf(m[3]), odr.getMethod());
+    }
+  }
+
+  @Test
+  public void extractMethodFail() {
+    String[][] mm = {
+        { "POST", "bla", null },
+        { "POST", "MERGE", "PATCH" },
+        { "OPTIONS", null, null },
+        { "HEAD", null, null },
+    };
+
+    for (String[] m : mm) {
+
+      HttpServletRequest hr = mock(HttpServletRequest.class);
+
+      when(hr.getMethod()).thenReturn(m[0]);
+      when(hr.getHeader("X-HTTP-Method")).thenReturn(m[1]);
+      when(hr.getHeader("X-HTTP-Method-Override")).thenReturn(m[2]);
+
+      ODataRequest odr = new ODataRequest();
+      try {
+        ODataHttpHandlerImpl.extractMethod(odr, hr);
+        fail();
+      } catch (ODataRuntimeException e) {}
+    }
+  }
+
+  @Test
+  public void extractUri() {
 
     //@formatter:off (Eclipse formatter)
     //CHECKSTYLE:OFF (Maven checkstyle)
     String [][] uris = {
         /* 0: host                    1: cp         2: sp       3: sr          4: od       5: qp        6: spl  */
+        {  "http://localhost",          "",           "",         "",          "",          "",         "0"},  
         {  "http://localhost",          "",           "",         "",          "/",         "",         "0"},  
         {  "http://localhost",          "",           "",         "",          "/od",       "",         "0"},  
         {  "http://localhost",          "",           "",         "",          "/od/",      "",         "0"},  
 
+        {  "http://localhost",          "/cp",        "",         "",          "",          "",         "0"},  
         {  "http://localhost",          "/cp",        "",         "",          "/",         "",         "0"},  
         {  "http://localhost",          "/cp",        "",         "",          "/od",       "",         "0"},  
+        {  "http://localhost",          "",           "/sp",      "",          "",          "",         "0"},  
         {  "http://localhost",          "",           "/sp",      "",          "/",         "",         "0"},  
         {  "http://localhost",          "",           "/sp",      "",          "/od",       "",         "0"},  
+        {  "http://localhost",          "",           "",         "/sr",       "",          "",         "1"},  
         {  "http://localhost",          "",           "",         "/sr",       "/",         "",         "1"},  
         {  "http://localhost",          "",           "",         "/sr",       "/od",       "",         "1"},  
+        {  "http://localhost",          "",           "",         "/sr/sr",    "",          "",         "2"},  
         {  "http://localhost",          "",           "",         "/sr/sr",    "/",         "",         "2"},  
         {  "http://localhost",          "",           "",         "/sr/sr",    "/od",       "",         "2"},  
 
+        {  "http://localhost",          "/cp",        "/sp",      "",          "",          "",         "0"},  
         {  "http://localhost",          "/cp",        "/sp",      "",          "/",         "",         "0"},  
         {  "http://localhost",          "/cp",        "/sp",      "",          "/od",       "",         "0"},  
         {  "http://localhost",          "/cp",        "",         "/sr",       "/",         "",         "1"},  
         {  "http://localhost",          "/cp",        "",         "/sr",       "/od",       "",         "1"},  
+        {  "http://localhost",          "",           "/sp",      "/sr",       "",          "",         "1"},  
         {  "http://localhost",          "",           "/sp",      "/sr",       "/",         "",         "1"},  
         {  "http://localhost",          "",           "/sp",      "/sr",       "/od",       "",         "1"},  
+        {  "http://localhost",          "/cp",        "/sp",      "/sr",       "",          "",         "1"},  
         {  "http://localhost",          "/cp",        "/sp",      "/sr",       "/",         "",         "1"},  
         {  "http://localhost",          "/cp",        "/sp",      "/sr",       "/od",       "",         "1"},  
         
+        {  "http://localhost",          "",           "",         "",          "",          "qp",       "0"},  
         {  "http://localhost",          "",           "",         "",          "/",         "qp",       "0"},  
         {  "http://localhost",          "/cp",        "/sp",      "/sr",       "/od",       "qp",       "1"},  
         
@@ -85,17 +157,19 @@ public class ODataHttpHandlerImplTest {
       when(hr.getServletPath()).thenReturn(p[2]);
 
       ODataRequest odr = new ODataRequest();
-      ODataHttpHandlerImpl.fillRequestUri(odr, hr, Integer.parseInt(p[6]));
+      ODataHttpHandlerImpl.extractUri(odr, hr, Integer.parseInt(p[6]));
 
       String rawBaseUri = p[0] + p[1] + p[2] + p[3];
       String rawODataPath = p[4];
       String rawQueryPath = "".equals(p[5]) ? null : p[5];
       String rawRequestUri = requestUrl + (queryString == null ? "" : "?" + queryString);
+      String rawServiceResolutionUri = "".equals(p[3]) ? null : p[3];
 
       assertEquals(rawBaseUri, odr.getRawBaseUri());
       assertEquals(rawODataPath, odr.getRawODataPath());
       assertEquals(rawQueryPath, odr.getRawQueryPath());
       assertEquals(rawRequestUri, odr.getRawRequestUri());
+      assertEquals(rawServiceResolutionUri, odr.getRawServiceResolutionUri());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7f5a119e/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 70e3bdf..5ce5a84 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
@@ -27,7 +27,7 @@ import javax.servlet.http.HttpServletResponse;
 
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.server.api.ODataHttpHandler;
-import org.apache.olingo.server.api.ODataServer;
+import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -42,28 +42,23 @@ public class TechnicalServlet extends HttpServlet {
   protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     LOG.debug("ReferenceServlet:service() called");
 
-    ODataServer server = ODataServer.newInstance();
-    Edm edm = server.createEdm(new EdmTechProvider());
+    OData odata = OData.newInstance();
+    Edm edm = odata.createEdm(new EdmTechProvider());
 
-    ODataHttpHandler handler = server.createHandler(edm);
+    ODataHttpHandler handler = odata.createHandler(edm);
     handler.process(req, resp);
   }
 
-//  public void bla(HttpServletRequest hr, HttpServletResponse hres) {
+  public void bla(HttpServletRequest hr, HttpServletResponse hres) {
 //    ODataServer s = ODataServer.newInstance();
 //
 //    ODataRequest r = s.createRequest(hr);
 //
 //    Edm edm = server.createEdm(new EdmTechProvider());
-//    ODataUriParser p = s.createUriParser(edm);
-// 
-//    ODataUriInfo i = p.parse(r);
-//
-//    ODataDispatcher d = s.createDispatcher(proc);
 //    
-//    ODataResponse res = d.dispatch();
+//    ODataResponse res = r.dispatch();
 //    
 //    s.sendResponse(res, hres);
-//  }
+  }
 
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7f5a119e/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java
index fe2f48c..3636c2b 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/ODataHandlerTest.java
@@ -25,7 +25,7 @@ import static org.junit.Assert.assertTrue;
 import org.apache.commons.io.IOUtils;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.http.HttpMethod;
-import org.apache.olingo.server.api.ODataServer;
+import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
 import org.junit.Before;
 import org.junit.Test;
@@ -36,7 +36,7 @@ public class ODataHandlerTest {
 
   @Before
   public void before() {
-    ODataServer server = ODataServer.newInstance();
+    OData server = OData.newInstance();
     Edm edm = server.createEdm(new EdmTechProvider());
 
     handler = new ODataHandler(server, edm);
@@ -47,7 +47,9 @@ public class ODataHandlerTest {
     ODataRequest request = new ODataRequest();
 
     request.setMethod(HttpMethod.GET);
-
+    request.setRawBaseUri("http://localhost/odata/");
+    request.setRawODataPath("");
+    
     ODataResponse response = handler.process(request);
 
     assertNotNull(response);
@@ -57,7 +59,7 @@ public class ODataHandlerTest {
     assertNotNull(response.getContent());
     String doc = IOUtils.toString(response.getContent());
 
-    assertTrue(doc.contains("\"@odata.context\" : \"http://root/$metadata\""));
+    assertTrue(doc.contains("\"@odata.context\" : \"http://localhost/odata/$metadata\""));
     assertTrue(doc.contains("\"value\" :"));
   }
 
@@ -66,7 +68,7 @@ public class ODataHandlerTest {
     ODataRequest request = new ODataRequest();
 
     request.setMethod(HttpMethod.GET);
-//    request.setUrl("http://localhost/odata/$metadata");
+    request.setRawODataPath("$metadata");
 
     ODataResponse response = handler.process(request);
 
@@ -76,10 +78,11 @@ public class ODataHandlerTest {
 
     assertNotNull(response.getContent());
     String doc = IOUtils.toString(response.getContent());
+
+    System.out.println(doc);
     
-    assertTrue(doc.contains("<edmx:Edmx Version=\"4.0\">"));
+    assertTrue(doc.contains("<edmx:Edmx Version=\"4.0\""));
 
   }
 
-  
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7f5a119e/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentTest.java
index 95ccfe9..35e816c 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ServiceDocumentTest.java
@@ -34,7 +34,7 @@ import org.apache.olingo.commons.api.edm.EdmEntityContainer;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
 import org.apache.olingo.commons.api.edm.EdmFunctionImport;
 import org.apache.olingo.commons.api.edm.EdmSingleton;
-import org.apache.olingo.server.api.ODataServer;
+import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.serializer.ODataFormat;
 import org.apache.olingo.server.api.serializer.ODataSerializer;
 import org.junit.Before;
@@ -108,7 +108,7 @@ public class ServiceDocumentTest {
   public void writeServiceDocumentJson() throws Exception {
     String serviceRoot = "http://localhost:8080/odata.svc";
 
-    ODataServer server = ODataServer.newInstance();
+    OData server = OData.newInstance();
     assertNotNull(server);
 
     ODataSerializer serializer = server.createSerializer(ODataFormat.JSON);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/7f5a119e/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentTest.java
index c17ed1f..475dff1 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/MetadataDocumentTest.java
@@ -35,7 +35,7 @@ import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.edm.Target;
-import org.apache.olingo.server.api.ODataServer;
+import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.edm.provider.Action;
 import org.apache.olingo.server.api.edm.provider.ActionImport;
 import org.apache.olingo.server.api.edm.provider.ComplexType;
@@ -65,20 +65,20 @@ public class MetadataDocumentTest {
 
   @Test(expected = ODataRuntimeException.class)
   public void metadataOnJsonResultsInException() {
-    ODataSerializer serializer = ODataServer.newInstance().createSerializer(ODataFormat.JSON);
+    ODataSerializer serializer = OData.newInstance().createSerializer(ODataFormat.JSON);
     serializer.metadataDocument(mock(Edm.class));
   }
 
   @Test
   public void writeMetadataWithEmptyMockedEdm() {
-    ODataSerializer serializer = ODataServer.newInstance().createSerializer(ODataFormat.XML);
+    ODataSerializer serializer = OData.newInstance().createSerializer(ODataFormat.XML);
     Edm edm = mock(Edm.class);
     serializer.metadataDocument(edm);
   }
 
   @Test
   public void writeMetadataWithLocalTestEdm() throws Exception {
-    ODataSerializer serializer = ODataServer.newInstance().createSerializer(ODataFormat.XML);
+    ODataSerializer serializer = OData.newInstance().createSerializer(ODataFormat.XML);
     Edm edm = new EdmProviderImpl(new TestMetadataProvider());
     InputStream metadata = serializer.metadataDocument(edm);
     assertNotNull(metadata);
@@ -147,7 +147,7 @@ public class MetadataDocumentTest {
 
   @Test
   public void writeMetadataWithTechnicalScenario() {
-    ODataSerializer serializer = ODataServer.newInstance().createSerializer(ODataFormat.XML);
+    ODataSerializer serializer = OData.newInstance().createSerializer(ODataFormat.XML);
     EdmProviderImpl edm = new EdmProviderImpl(new EdmTechProvider());
     InputStream metadata = serializer.metadataDocument(edm);
     assertNotNull(metadata);