You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by tb...@apache.org on 2014/06/24 13:45:59 UTC
git commit: Prototype: Protocol Buffer Support
Repository: olingo-odata2
Updated Branches:
refs/heads/ProtocolBufferPrototype [created] 62bc99e37
Prototype: Protocol Buffer Support
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/62bc99e3
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/62bc99e3
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/62bc99e3
Branch: refs/heads/ProtocolBufferPrototype
Commit: 62bc99e37a209c35f58fb91c7a2bd58f7f8b9bf6
Parents: f86e307
Author: Tamara Boehm <ta...@sap.com>
Authored: Tue Jun 24 13:20:51 2014 +0200
Committer: Tamara Boehm <ta...@sap.com>
Committed: Tue Jun 24 13:20:51 2014 +0200
----------------------------------------------------------------------
odata2-lib/odata-ref/pom.xml | 100 +++++++++-----
.../odata2/ref/processor/ListsProcessor.java | 131 +++++++++++++++++++
2 files changed, 200 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/62bc99e3/odata2-lib/odata-ref/pom.xml
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-ref/pom.xml b/odata2-lib/odata-ref/pom.xml
index 84a49d5..434966f 100644
--- a/odata2-lib/odata-ref/pom.xml
+++ b/odata2-lib/odata-ref/pom.xml
@@ -1,22 +1,14 @@
<?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.
--->
+<!-- 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>
@@ -69,6 +61,47 @@
</instructions>
</configuration>
</plugin>
+ <plugin>
+ <groupId>de.softwareforge.mojo</groupId>
+ <artifactId>maven-protoc-plugin</artifactId>
+ <version>0.2-HPS-2</version>
+ <executions>
+ <execution>
+ <id>generate-sources</id>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ <phase>generate-sources</phase>
+ <configuration>
+ <protoSourceRoot>${basedir}/src/main/resources/</protoSourceRoot>
+ <includes>
+ <param>**/*.proto</param>
+ </includes>
+ </configuration>
+ </execution>
+ </executions>
+ <configuration>
+ <protocExecutable>/usr/local/bin/protoc</protocExecutable>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>add-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${project.build.directory}/generated-sources/java/</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
@@ -84,7 +117,7 @@
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
-
+
<dependency>
<groupId>org.apache.olingo</groupId>
<artifactId>olingo-odata2-core</artifactId>
@@ -97,18 +130,23 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <version>${mockito.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>${junit.version}</version>
- <scope>test</scope>
- </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>${mockito.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.protobuf</groupId>
+ <artifactId>protobuf-java</artifactId>
+ <version>2.5.0</version>
+ </dependency>
</dependencies>
</project>
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/62bc99e3/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ListsProcessor.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ListsProcessor.java b/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ListsProcessor.java
index 7e22a3d..e6781f3 100644
--- a/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ListsProcessor.java
+++ b/odata2-lib/odata-ref/src/main/java/org/apache/olingo/odata2/ref/processor/ListsProcessor.java
@@ -18,9 +18,13 @@
******************************************************************************/
package org.apache.olingo.odata2.ref.processor;
+import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -76,9 +80,11 @@ import org.apache.olingo.odata2.api.exception.ODataHttpException;
import org.apache.olingo.odata2.api.exception.ODataNotFoundException;
import org.apache.olingo.odata2.api.exception.ODataNotImplementedException;
import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.api.processor.ODataProcessor;
import org.apache.olingo.odata2.api.processor.ODataRequest;
import org.apache.olingo.odata2.api.processor.ODataResponse;
import org.apache.olingo.odata2.api.processor.ODataSingleProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntitySetProcessor;
import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
import org.apache.olingo.odata2.api.uri.KeyPredicate;
import org.apache.olingo.odata2.api.uri.NavigationSegment;
@@ -111,8 +117,15 @@ import org.apache.olingo.odata2.api.uri.info.GetMediaResourceUriInfo;
import org.apache.olingo.odata2.api.uri.info.GetSimplePropertyUriInfo;
import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
+import org.apache.olingo.odata2.core.ep.util.CircleStreamBuffer;
+import org.apache.olingo.odata2.ref.model.AddressBookProtos;
import org.apache.olingo.odata2.ref.processor.ScenarioDataSource.BinaryData;
+import com.google.protobuf.Descriptors;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.GeneratedMessage;
+import com.google.protobuf.Message;
+
/**
* Implementation of the centralized parts of OData processing,
* allowing to use the simplified DataSource for the
@@ -121,10 +134,24 @@ import org.apache.olingo.odata2.ref.processor.ScenarioDataSource.BinaryData;
*/
public class ListsProcessor extends ODataSingleProcessor {
+ private static final String CUSTOM_CONTENT_TYPE = "application/x-protobuf";
// TODO: Paging size should be configurable.
private static final int SERVER_PAGING_SIZE = 100;
private final BeanPropertyAccess valueAccess;
private final ScenarioDataSource dataSource;
+ private static Map<String, String> mapping;
+ static {
+ mapping = new HashMap<String, String>();
+ mapping.put("org.apache.olingo.odata2.ref.model.Room", "org.apache.olingo.odata2.ref.model.AddressBookProtos$Room");
+ mapping.put("org.apache.olingo.odata2.ref.model.Employee",
+ "org.apache.olingo.odata2.ref.model.AddressBookProtos$Employee");
+ mapping.put("org.apache.olingo.odata2.ref.model.Manager",
+ "org.apache.olingo.odata2.ref.model.AddressBookProtos$Employee");
+ mapping.put("org.apache.olingo.odata2.ref.model.Location",
+ "org.apache.olingo.odata2.ref.model.AddressBookProtos$Employee$Location");
+ mapping.put("org.apache.olingo.odata2.ref.model.City",
+ "org.apache.olingo.odata2.ref.model.AddressBookProtos$Employee$City");
+ }
public ListsProcessor(final ScenarioDataSource dataSource) {
this(dataSource, new BeanPropertyAccess());
@@ -136,6 +163,21 @@ public class ListsProcessor extends ODataSingleProcessor {
}
@Override
+ public List<String> getCustomContentTypes(final Class<? extends ODataProcessor> processorFeature)
+ throws ODataException {
+ if (processorFeature == EntitySetProcessor.class) {
+ List<String> customContentTypes = new ArrayList<String>();
+ // otherwise fit fails if no media type has been entered
+ customContentTypes.add(HttpContentType.APPLICATION_ATOM_XML_FEED_UTF8);
+ customContentTypes.add(CUSTOM_CONTENT_TYPE);
+ return customContentTypes;
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override
public ODataResponse readEntitySet(final GetEntitySetUriInfo uriInfo, final String contentType)
throws ODataException {
ArrayList<Object> data = new ArrayList<Object>();
@@ -191,6 +233,47 @@ public class ListsProcessor extends ODataSingleProcessor {
final EdmEntityType entityType = entitySet.getEntityType();
List<Map<String, Object>> values = new ArrayList<Map<String, Object>>();
+
+ if (CUSTOM_CONTENT_TYPE.equals(contentType)) {
+ Descriptors.Descriptor addressBookDescriptor = AddressBookProtos.AddressBook.getDescriptor();
+ AddressBookProtos.AddressBook.Builder addressBook = AddressBookProtos.AddressBook.newBuilder();
+ CircleStreamBuffer buffer = new CircleStreamBuffer();
+ try {
+ for (final Object entryData : data) {
+ String className = mapping.get(entryData.getClass().getName());
+
+ Class<Message> object = (Class<Message>) Class.forName(className);
+ Descriptors.Descriptor descriptor = ( Descriptors.Descriptor) object.getMethod("getDescriptor").invoke(object);
+ GeneratedMessage.Builder builder = (GeneratedMessage.Builder) object.getMethod("newBuilder").invoke(object);
+ Message message = getStructuralTypeValueMapProtobuf(entryData, descriptor,
+ builder, entityType);
+
+ FieldDescriptor fd = addressBookDescriptor.findFieldByName(descriptor.getName().toLowerCase());
+ if (fd != null) {
+ addressBook.addRepeatedField(fd, message);
+ }
+ }
+ OutputStream output = buffer.getOutputStream();
+
+
+ addressBook.build().writeTo(output);
+ } catch (IOException e) {
+ throw new ODataException(e);
+ } catch (IllegalArgumentException e) {
+ throw new ODataException(e);
+ } catch (SecurityException e) {
+ throw new ODataException(e);
+ } catch (IllegalAccessException e) {
+ throw new ODataException(e);
+ } catch (InvocationTargetException e) {
+ throw new ODataException(e);
+ } catch (NoSuchMethodException e) {
+ throw new ODataException(e);
+ } catch (ClassNotFoundException e) {
+ throw new ODataException(e);
+ }
+ return ODataResponse.entity(buffer.getInputStream()).build();
+ }
for (final Object entryData : data) {
values.add(getStructuralTypeValueMap(entryData, entityType));
}
@@ -1522,7 +1605,55 @@ public class ListsProcessor extends ODataSingleProcessor {
}
}
}
+ private Message getStructuralTypeValueMapProtobuf(final Object data, final Descriptors.Descriptor descriptor,
+ final GeneratedMessage.Builder message,
+ final EdmStructuralType type) throws ODataException {
+ // String cname = data.getClass().getName();
+ Map<String, Object> valueMap = new HashMap<String, Object>();
+
+ for (final String propertyName : type.getPropertyNames()) {
+ final EdmProperty property = (EdmProperty) type.getProperty(propertyName);
+ final Object value = valueAccess.getPropertyValue(data, property);
+ Descriptors.FieldDescriptor fieldDescriptor = descriptor.findFieldByName(propertyName.toLowerCase());
+ if(value!=null){
+ if (property.isSimple()) {
+ if(value instanceof Calendar){
+ message.setField(fieldDescriptor, ((Calendar)value).getTimeInMillis());
+ } else{
+ message.setField(fieldDescriptor, value);
+ }
+
+ } else {
+ String className = mapping.get(value.getClass().getName());
+
+ Class<Message> object;
+ try {
+ object = (Class<Message>) Class.forName(className);
+ Descriptors.Descriptor descr = ( Descriptors.Descriptor) object.getMethod("getDescriptor").invoke(object);
+ GeneratedMessage.Builder builder = (GeneratedMessage.Builder) object.getMethod("newBuilder").invoke(object);
+ message.setField(fieldDescriptor, getStructuralTypeValueMapProtobuf(value,descr,
+ builder, (EdmStructuralType) property.getType()));
+ } catch (ClassNotFoundException e) {
+ throw new ODataException(e);
+ } catch (IllegalArgumentException e) {
+ throw new ODataException(e);
+ } catch (SecurityException e) {
+ throw new ODataException(e);
+ } catch (IllegalAccessException e) {
+ throw new ODataException(e);
+ } catch (InvocationTargetException e) {
+ throw new ODataException(e);
+ } catch (NoSuchMethodException e) {
+ throw new ODataException(e);
+ }
+
+ }
+ }
+ }
+ return message.build();
+ }
+
private <T> Map<String, Object> getSimpleTypeValueMap(final T data, final List<EdmProperty> propertyPath)
throws ODataException {
final EdmProperty property = propertyPath.get(propertyPath.size() - 1);