You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2014/11/13 06:37:36 UTC

olingo-odata2 git commit: Added support for Spring

Repository: olingo-odata2
Updated Branches:
  refs/heads/OLINGO-193_SpringSupport [created] 5a93f4cc4


Added support for Spring

Signed-off-by: Michael Bolz <mi...@sap.com>


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/5a93f4cc
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/5a93f4cc
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/5a93f4cc

Branch: refs/heads/OLINGO-193_SpringSupport
Commit: 5a93f4cc4e7c14759b1f3e8d1022c02978573646
Parents: 0c4bac5
Author: Lior Okman <li...@sap.com>
Authored: Wed Nov 12 20:25:43 2014 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Thu Nov 13 06:35:57 2014 +0100

----------------------------------------------------------------------
 .../core/rest/spring/ODataRootLocator.java      | 141 +++++++++++++++++++
 odata2-lib/odata-spring/pom.xml                 |  39 +++++
 .../odata2/spring/OlingoNamespaceHandler.java   |  13 ++
 .../spring/OlingoServerDefinitionParser.java    |  73 ++++++++++
 .../src/main/resources/META-INF/spring.handlers |   1 +
 .../src/main/resources/META-INF/spring.schemas  |   1 +
 .../src/main/resources/schema/olingo.xsd        |  23 +++
 odata2-lib/pom.xml                              |   1 +
 pom.xml                                         |   2 +
 9 files changed, 294 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5a93f4cc/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rest/spring/ODataRootLocator.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rest/spring/ODataRootLocator.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rest/spring/ODataRootLocator.java
new file mode 100755
index 0000000..295dc9d
--- /dev/null
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/rest/spring/ODataRootLocator.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * 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.odata2.core.rest.spring;
+
+import java.util.List;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Encoded;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.PathSegment;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.olingo.odata2.api.ODataServiceFactory;
+import org.apache.olingo.odata2.api.exception.ODataBadRequestException;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.core.rest.ODataRedirectLocator;
+import org.apache.olingo.odata2.core.rest.ODataSubLocator;
+import org.apache.olingo.odata2.core.rest.SubLocatorParameter;
+
+/**
+ * Default OData root locator responsible to handle the whole path and delegate all calls to a sub locator:<p>
+ * <code>/{odata path} e.g. http://host:port/webapp/odata.svc/$metadata</code><br>
+ * All path segments defined by a servlet mapping belong to the odata uri.
+ * </p>
+ * This behavior can be changed:<p>
+ * <code>/{custom path}{odata path} e.g. http://host:port/webapp/bmw/odata.svc/$metadata</code><br>
+ * The first segment defined by a servlet mapping belong to customer context and the following segments are OData
+ * specific.
+ * </p>
+ *
+ */
+@Path("/")
+public class ODataRootLocator {
+
+  @Context
+  private HttpHeaders httpHeaders;
+  @Context
+  private UriInfo uriInfo;
+  @Context
+  private Request request;
+  @Context
+  private ServletConfig servletConfig;
+  @Context
+  private HttpServletRequest servletRequest;
+
+  @Context
+  private Application app;
+
+  // These next two members are exposed so that they can be injected with Spring
+  private ODataServiceFactory serviceFactory;
+  private int pathSplit = 0;
+
+  /**
+   * Default root behavior which will delegate all paths to a ODataLocator.
+   * @param pathSegments URI path segments - all segments have to be OData
+   * @param xHttpMethod HTTP Header X-HTTP-Method for tunneling through POST
+   * @param xHttpMethodOverride HTTP Header X-HTTP-Method-Override for tunneling through POST
+   * @return a locator handling OData protocol
+   * @throws ODataException
+   * @throws ClassNotFoundException
+   * @throws IllegalAccessException
+   * @throws InstantiationException
+   */
+  @Path("/{pathSegments: .*}")
+  public Object handleRequest(
+      @Encoded @PathParam("pathSegments") final List<PathSegment> pathSegments,
+      @HeaderParam("X-HTTP-Method") final String xHttpMethod,
+      @HeaderParam("X-HTTP-Method-Override") final String xHttpMethodOverride)
+      throws ODataException, ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+    if (xHttpMethod != null && xHttpMethodOverride != null) {
+
+      /*
+       * X-HTTP-Method-Override : implemented by CXF
+       * X-HTTP-Method : implemented in ODataSubLocator:handlePost
+       */
+
+      if (!xHttpMethod.equalsIgnoreCase(xHttpMethodOverride)) {
+        throw new ODataBadRequestException(ODataBadRequestException.AMBIGUOUS_XMETHOD);
+      }
+    }
+
+    if (servletRequest.getPathInfo() == null) {
+      return handleRedirect();
+    }
+
+    final SubLocatorParameter param = new SubLocatorParameter();
+    param.setServiceFactory(serviceFactory);
+    param.setPathSegments(pathSegments);
+    param.setHttpHeaders(httpHeaders);
+    param.setUriInfo(uriInfo);
+    param.setRequest(request);
+    param.setServletRequest(servletRequest);
+    param.setPathSplit(pathSplit);
+
+    return ODataSubLocator.create(param);
+  }
+
+  private Object handleRedirect() {
+    return new ODataRedirectLocator();
+  }
+
+  public ODataServiceFactory getServiceFactory() {
+	return serviceFactory;
+  }
+
+  public void setServiceFactory(ODataServiceFactory serviceFactory) {
+	this.serviceFactory = serviceFactory;
+  }
+
+  public int getPathSplit() {
+	return pathSplit;
+  }
+
+  public void setPathSplit(int pathSplit) {
+	this.pathSplit = pathSplit;
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5a93f4cc/odata2-lib/odata-spring/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-spring/pom.xml b/odata2-lib/odata-spring/pom.xml
new file mode 100755
index 0000000..8602fcc
--- /dev/null
+++ b/odata2-lib/odata-spring/pom.xml
@@ -0,0 +1,39 @@
+<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-spring</artifactId>
+	<name>${project.artifactId}</name>
+
+	<parent>
+		<groupId>org.apache.olingo</groupId>
+		<artifactId>olingo-odata2-lib</artifactId>
+		<version>2.0.2-SNAPSHOT</version>
+	</parent>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-beans</artifactId>
+			<version>${spring.version}</version>
+			<exclusions>
+				<exclusion>
+					<groupId>commons-logging</groupId>
+					<artifactId>commons-logging</artifactId>
+				</exclusion>
+			</exclusions>
+			<optional>true</optional>
+		</dependency>
+
+		<dependency>
+			<groupId>${project.groupId}</groupId>
+			<version>${project.version}</version>
+			<artifactId>olingo-odata2-core</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.cxf</groupId>
+			<artifactId>cxf-rt-frontend-jaxrs</artifactId>
+			<version>${cxf.version}</version>
+		</dependency>
+	</dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5a93f4cc/odata2-lib/odata-spring/src/main/java/org/apache/olingo/odata2/spring/OlingoNamespaceHandler.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-spring/src/main/java/org/apache/olingo/odata2/spring/OlingoNamespaceHandler.java b/odata2-lib/odata-spring/src/main/java/org/apache/olingo/odata2/spring/OlingoNamespaceHandler.java
new file mode 100755
index 0000000..a141dde
--- /dev/null
+++ b/odata2-lib/odata-spring/src/main/java/org/apache/olingo/odata2/spring/OlingoNamespaceHandler.java
@@ -0,0 +1,13 @@
+package org.apache.olingo.odata2.spring;
+
+import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+
+
+public class OlingoNamespaceHandler extends NamespaceHandlerSupport {
+
+	@Override
+	public void init() {
+		registerBeanDefinitionParser("server", new OlingoServerDefinitionParser());
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5a93f4cc/odata2-lib/odata-spring/src/main/java/org/apache/olingo/odata2/spring/OlingoServerDefinitionParser.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-spring/src/main/java/org/apache/olingo/odata2/spring/OlingoServerDefinitionParser.java b/odata2-lib/odata-spring/src/main/java/org/apache/olingo/odata2/spring/OlingoServerDefinitionParser.java
new file mode 100755
index 0000000..849e7a8
--- /dev/null
+++ b/odata2-lib/odata-spring/src/main/java/org/apache/olingo/odata2/spring/OlingoServerDefinitionParser.java
@@ -0,0 +1,73 @@
+package org.apache.olingo.odata2.spring;
+
+import org.apache.cxf.jaxrs.spring.JAXRSServerFactoryBeanDefinitionParser;
+import org.apache.olingo.odata2.core.rest.ODataExceptionMapperImpl;
+import org.apache.olingo.odata2.core.rest.app.ODataApplication;
+import org.apache.olingo.odata2.core.rest.spring.ODataRootLocator;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanDefinitionHolder;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+public class OlingoServerDefinitionParser extends JAXRSServerFactoryBeanDefinitionParser {
+
+	public OlingoServerDefinitionParser() {
+		super();
+		setBeanClass(SpringJAXRSServerFactoryBean.class);
+	}
+
+	@Override
+	protected void mapAttribute(BeanDefinitionBuilder bean, Element e,  String name, String val) {
+		if ("id".equals(name) || "address".equals(name)) {
+			mapToProperty(bean, name, val);
+		}
+	}
+
+	@Override
+	protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder bean) {
+		super.doParse(element, parserContext, bean);
+		ManagedList<BeanDefinition> services = new ManagedList<BeanDefinition>(3);
+
+		if (!parserContext.getRegistry().containsBeanDefinition("OlingoODataExceptionHandler")) {
+			AbstractBeanDefinition definition = BeanDefinitionBuilder.genericBeanDefinition(ODataExceptionMapperImpl.class).getBeanDefinition();
+			definition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
+			BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, "OlingoODataExceptionHandler", new String[0]);
+			registerBeanDefinition(holder, parserContext.getRegistry());
+		}
+
+		if (!parserContext.getRegistry().containsBeanDefinition("OlingoODataProvider")) {
+			AbstractBeanDefinition definition = BeanDefinitionBuilder.genericBeanDefinition(ODataApplication.MyProvider.class).getBeanDefinition();
+			definition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
+			BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, "OlingoODataProvider", new String[0]);
+			registerBeanDefinition(holder, parserContext.getRegistry());
+		}
+
+		if (!element.hasAttribute("factory")) {
+			if (!parserContext.getRegistry().containsBeanDefinition("OlingoODataRootLocator")) {
+				AbstractBeanDefinition definition = BeanDefinitionBuilder.genericBeanDefinition(ODataRootLocator.class).getBeanDefinition();
+				definition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
+				BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, "OlingoODataRootLocator", new String[0]);
+				registerBeanDefinition(holder, parserContext.getRegistry());
+			}
+			services.add(parserContext.getRegistry().getBeanDefinition("OlingoODataRootLocator"));
+		}
+		else {
+			BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ODataRootLocator.class);
+			builder.setScope(BeanDefinition.SCOPE_PROTOTYPE);
+			builder.addPropertyReference("serviceFactory", element.getAttribute("factory"));
+			AbstractBeanDefinition definition = builder.getBeanDefinition();
+			BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, "OlingoODataRootLocator-"+element.getAttribute("factory"), new String[0]);
+			registerBeanDefinition(holder, parserContext.getRegistry());
+			services.add(definition);
+
+		}
+
+		services.add(parserContext.getRegistry().getBeanDefinition("OlingoODataExceptionHandler"));
+		services.add(parserContext.getRegistry().getBeanDefinition("OlingoODataProvider"));
+		bean.addPropertyValue("serviceBeans", services);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5a93f4cc/odata2-lib/odata-spring/src/main/resources/META-INF/spring.handlers
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-spring/src/main/resources/META-INF/spring.handlers b/odata2-lib/odata-spring/src/main/resources/META-INF/spring.handlers
new file mode 100755
index 0000000..6f63fc8
--- /dev/null
+++ b/odata2-lib/odata-spring/src/main/resources/META-INF/spring.handlers
@@ -0,0 +1 @@
+http\://www.apache.org/olingo/odata2/spring/namespace=org.apache.olingo.odata2.spring.OlingoNamespaceHandler

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5a93f4cc/odata2-lib/odata-spring/src/main/resources/META-INF/spring.schemas
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-spring/src/main/resources/META-INF/spring.schemas b/odata2-lib/odata-spring/src/main/resources/META-INF/spring.schemas
new file mode 100755
index 0000000..85b9a6d
--- /dev/null
+++ b/odata2-lib/odata-spring/src/main/resources/META-INF/spring.schemas
@@ -0,0 +1 @@
+http\://www.apache.org/olingo/odata2/spring/namespace.xsd=schema/olingo.xsd

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5a93f4cc/odata2-lib/odata-spring/src/main/resources/schema/olingo.xsd
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-spring/src/main/resources/schema/olingo.xsd b/odata2-lib/odata-spring/src/main/resources/schema/olingo.xsd
new file mode 100755
index 0000000..2b160e9
--- /dev/null
+++ b/odata2-lib/odata-spring/src/main/resources/schema/olingo.xsd
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns="http://www.apache.org/olingo/odata2/spring/namespace"
+	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+	xmlns:beans="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:jaxrs="http://cxf.apache.org/jaxrs"
+	targetNamespace="http://www.apache.org/olingo/odata2/spring/namespace"
+	elementFormDefault="unqualified">
+
+	<xsd:import namespace="http://www.springframework.org/schema/beans"
+				schemaLocation="http://www.springframework.org/schema/beans/spring-beans.xsd"/>
+
+	<xsd:element name="server">
+		<xsd:complexType>
+			<xsd:complexContent>
+				<xsd:extension base="beans:identifiedType">
+					<xsd:attribute name="address" type="xsd:string" use="required"/>
+					<xsd:attribute name="factory" type="xsd:string" use="optional"/>
+				</xsd:extension>
+			</xsd:complexContent>
+		</xsd:complexType>
+	</xsd:element>
+</xsd:schema>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5a93f4cc/odata2-lib/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-lib/pom.xml b/odata2-lib/pom.xml
index c646f3f..f510ec7 100644
--- a/odata2-lib/pom.xml
+++ b/odata2-lib/pom.xml
@@ -30,5 +30,6 @@
         <module>odata-fit</module>
         <module>odata-ref</module>
         <module>odata-web</module>
+        <module>odata-spring</module>
     </modules>
 </project>

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/5a93f4cc/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index fbe059e..67ae922 100644
--- a/pom.xml
+++ b/pom.xml
@@ -72,6 +72,8 @@
 
 		<version.eclipselink>2.5.1</version.eclipselink>
 		<version.javax.persistence>2.0.5</version.javax.persistence>
+
+		<spring.version>3.2.12.RELEASE</spring.version>
 	</properties>
 
 	<modules>