[OLINGO-260] provided primitive keys integration test on proxy + some refactoring ... still missing EdmTime review: what about BigDecimal in place of Duration?

This commit is contained in:
fmartelli 2014-05-13 18:59:14 +02:00
parent 3daee521b4
commit 32518c1b0b
17 changed files with 579 additions and 242 deletions

View File

@ -193,14 +193,7 @@ abstract class AbstractInvocationHandler<C extends CommonEdmEnabledODataClient<?
final EdmTypeInfo edmType = new EdmTypeInfo.Builder().
setEdm(client.getCachedEdm()).setTypeExpression(annotation.returnType()).build();
if (edmType.isEnumType()) {
throw new UnsupportedOperationException("Usupported enum type " + edmType.getFullQualifiedName());
}
if (edmType.isPrimitiveType() || edmType.isComplexType()) {
return CoreUtils.getValueFromProperty(client, (CommonODataProperty) result, method.getGenericReturnType());
}
if (edmType.isEntityType()) {
if (edmType.isCollection()) {
final ParameterizedType collType = (ParameterizedType) method.getReturnType().getGenericInterfaces()[0];
@ -220,9 +213,9 @@ abstract class AbstractInvocationHandler<C extends CommonEdmEnabledODataClient<?
method.getReturnType(),
false);
}
}else{
return CoreUtils.getValueFromProperty(client, (CommonODataProperty) result, method.getGenericReturnType(), null);
}
throw new IllegalArgumentException("Could not process the functionImport information");
}
@Override

View File

@ -20,7 +20,6 @@ package org.apache.olingo.ext.proxy.commons;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.util.ArrayList;
@ -32,7 +31,6 @@ import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
import org.apache.olingo.commons.api.domain.CommonODataProperty;
import org.apache.olingo.commons.api.domain.ODataComplexValue;
import org.apache.olingo.commons.api.domain.ODataLinked;
import org.apache.olingo.commons.api.domain.ODataValue;
import org.apache.olingo.commons.api.edm.EdmElement;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.core.edm.EdmTypeInfo;
@ -77,7 +75,7 @@ public class ComplexTypeInvocationHandler<C extends CommonEdmEnabledODataClient<
}
@SuppressWarnings({"unchecked", "rawtypes"})
static ComplexTypeInvocationHandler<?> getInstance(
public static ComplexTypeInvocationHandler<?> getInstance(
final CommonEdmEnabledODataClient<?> client,
final ODataComplexValue<?> complex,
final Class<?> typeRef,
@ -112,48 +110,7 @@ public class ComplexTypeInvocationHandler<C extends CommonEdmEnabledODataClient<
@Override
protected Object getPropertyValue(final String name, final Type type) {
try {
final Object res;
final CommonODataProperty property = getComplex().get(name);
if (property == null) {
res = null;
} else if (property.hasComplexValue()) {
res = Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
new Class<?>[] {(Class<?>) type},
ComplexTypeInvocationHandler.getInstance(
client, property.getValue().asComplex(), (Class<?>) type, targetHandler));
} else if (property.hasCollectionValue()) {
final ParameterizedType collType = (ParameterizedType) type;
final Class<?> collItemClass = (Class<?>) collType.getActualTypeArguments()[0];
final ArrayList<Object> collection = new ArrayList<Object>();
final Iterator<ODataValue> collPropItor = property.getValue().asCollection().iterator();
while (collPropItor.hasNext()) {
final ODataValue value = collPropItor.next();
if (value.isPrimitive()) {
collection.add(CoreUtils.primitiveValueToObject(value.asPrimitive()));
} else if (value.isComplex()) {
final Object collItem = Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
new Class<?>[] {collItemClass},
ComplexTypeInvocationHandler.getInstance(
client, value.asComplex(), collItemClass, targetHandler));
collection.add(collItem);
}
}
res = collection;
} else {
res = type == null
? CoreUtils.getValueFromProperty(client, property)
: CoreUtils.getValueFromProperty(client, property, type);
}
return res;
return CoreUtils.getValueFromProperty(client, getComplex().get(name), type, targetHandler);
} catch (Exception e) {
throw new IllegalArgumentException("Error getting value for property '" + name + "'", e);
}

View File

@ -21,15 +21,11 @@ package org.apache.olingo.ext.proxy.commons;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.commons.io.IOUtils;
@ -40,7 +36,6 @@ import org.apache.olingo.client.core.uri.URIUtils;
import org.apache.olingo.commons.api.domain.CommonODataEntity;
import org.apache.olingo.commons.api.domain.CommonODataProperty;
import org.apache.olingo.commons.api.domain.ODataLinked;
import org.apache.olingo.commons.api.domain.ODataValue;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.format.ODataMediaFormat;
@ -194,45 +189,8 @@ public class EntityTypeInvocationHandler<C extends CommonEdmEnabledODataClient<?
Object res;
if (propertyChanges.containsKey(name)) {
res = propertyChanges.get(name);
} else if (property == null) {
res = null;
} else if (property.hasComplexValue()) {
res = Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
new Class<?>[] {(Class<?>) type},
ComplexTypeInvocationHandler.getInstance(
client, property.getValue().asComplex(), (Class<?>) type, this));
addPropertyChanges(name, res);
} else if (property.hasCollectionValue()) {
final ParameterizedType collType = (ParameterizedType) type;
final Class<?> collItemClass = (Class<?>) collType.getActualTypeArguments()[0];
final ArrayList<Object> collection = new ArrayList<Object>();
final Iterator<ODataValue> collPropItor = property.getValue().asCollection().iterator();
while (collPropItor.hasNext()) {
final ODataValue value = collPropItor.next();
if (value.isPrimitive()) {
collection.add(CoreUtils.primitiveValueToObject(value.asPrimitive()));
} else if (value.isComplex()) {
final Object collItem = Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
new Class<?>[] {collItemClass},
ComplexTypeInvocationHandler.getInstance(
client, value.asComplex(), collItemClass, this));
collection.add(collItem);
}
}
res = collection;
addPropertyChanges(name, res);
} else {
res = type == null
? CoreUtils.getValueFromProperty(client, property)
: CoreUtils.getValueFromProperty(client, property, type);
res = CoreUtils.getValueFromProperty(client, property, type, this);
if (res != null) {
addPropertyChanges(name, res);

View File

@ -33,10 +33,8 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import org.apache.olingo.client.api.CommonEdmEnabledODataClient;
import org.apache.olingo.client.api.v3.UnsupportedInV3Exception;
import org.apache.olingo.client.core.edm.xml.AbstractComplexType;
import org.apache.olingo.commons.api.domain.CommonODataEntity;
import org.apache.olingo.commons.api.domain.CommonODataProperty;
import org.apache.olingo.commons.api.domain.ODataLink;
@ -48,12 +46,12 @@ import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.commons.core.edm.EdmTypeInfo;
import org.apache.olingo.ext.proxy.api.annotations.ComplexType;
import org.apache.olingo.ext.proxy.api.annotations.CompoundKeyElement;
import org.apache.olingo.ext.proxy.api.annotations.Key;
import org.apache.olingo.ext.proxy.api.annotations.Property;
import org.apache.olingo.ext.proxy.commons.AbstractTypeInvocationHandler;
import org.apache.olingo.ext.proxy.commons.ComplexTypeInvocationHandler;
import org.apache.olingo.ext.proxy.commons.EntityTypeInvocationHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -375,97 +373,59 @@ public final class CoreUtils {
@SuppressWarnings("unchecked")
public static Object getValueFromProperty(
final CommonEdmEnabledODataClient<?> client, final CommonODataProperty property)
final CommonEdmEnabledODataClient<?> client,
final CommonODataProperty property,
final Type typeRef,
final EntityTypeInvocationHandler<?> entityHandler)
throws InstantiationException, IllegalAccessException {
final Object value;
final Object res;
if (property == null || property.hasNullValue()) {
value = null;
} else if (property.hasCollectionValue()) {
value = new ArrayList<Object>();
final Iterator<ODataValue> collPropItor = property.getValue().asCollection().iterator();
while (collPropItor.hasNext()) {
final ODataValue odataValue = collPropItor.next();
if (odataValue.isPrimitive()) {
((Collection) value).add(primitiveValueToObject(odataValue.asPrimitive()));
}
if (odataValue.isComplex()) {
final Object collItem =
buildComplexInstance(client, property.getName(), odataValue.asComplex().iterator());
((Collection) value).add(collItem);
}
}
} else if (property.hasPrimitiveValue()) {
value = primitiveValueToObject(property.getPrimitiveValue());
} else if (property.hasComplexValue()) {
value = buildComplexInstance(client, property.getValue().asComplex().getTypeName(),
property.getValue().asComplex().iterator());
Class<?> internalRef;
if (typeRef == null) {
internalRef = null;
} else {
throw new IllegalArgumentException("Invalid property " + property);
}
return value;
}
@SuppressWarnings("unchecked")
private static <C extends AbstractComplexType> C buildComplexInstance(
final CommonEdmEnabledODataClient<?> client,
final String name,
final Iterator<CommonODataProperty> properties) {
for (C complex : (Iterable<C>) ServiceLoader.load(AbstractComplexType.class)) {
final ComplexType ann = complex.getClass().getAnnotation(ComplexType.class);
final String fn = ann == null ? null : ClassUtils.getNamespace(complex.getClass()) + "." + ann.name();
if (name.equals(fn)) {
populate(client, complex, Property.class, properties);
return complex;
try {
internalRef = (Class<?>) ((ParameterizedType) typeRef).getActualTypeArguments()[0];
} catch (ClassCastException e) {
internalRef = (Class<?>) typeRef;
}
}
return null;
}
@SuppressWarnings({"unchecked", "rawtypes"})
public static Object getValueFromProperty(
final CommonEdmEnabledODataClient<?> client,
final CommonODataProperty property, final Type type)
throws InstantiationException, IllegalAccessException {
final Object value;
if (property == null || property.hasNullValue()) {
value = null;
} else if (property.hasCollectionValue()) {
value = new ArrayList();
res = null;
} else if (property.hasComplexValue()) {
res = Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
new Class<?>[] {internalRef},
ComplexTypeInvocationHandler.getInstance(
client, property.getValue().asComplex(), internalRef, entityHandler));
final ParameterizedType collType = (ParameterizedType) type;
final Class<?> collItemClass = (Class<?>) collType.getActualTypeArguments()[0];
} else if (property.hasCollectionValue()) {
final ArrayList<Object> collection = new ArrayList<Object>();
final Iterator<ODataValue> collPropItor = property.getValue().asCollection().iterator();
while (collPropItor.hasNext()) {
final ODataValue odataValue = collPropItor.next();
if (odataValue.isPrimitive()) {
((Collection) value).add(primitiveValueToObject(odataValue.asPrimitive()));
}
if (odataValue.isComplex()) {
final ODataValue value = collPropItor.next();
if (value.isPrimitive()) {
collection.add(CoreUtils.primitiveValueToObject(value.asPrimitive()));
} else if (value.isComplex()) {
final Object collItem = Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
new Class<?>[] {collItemClass},
new ComplexTypeInvocationHandler(client, odataValue.asComplex(), collItemClass, null));
populate(client, collItem, Property.class, odataValue.asComplex().iterator());
((Collection) value).add(collItem);
new Class<?>[] {internalRef},
ComplexTypeInvocationHandler.getInstance(
client, value.asComplex(), internalRef, entityHandler));
collection.add(collItem);
}
}
} else if (property.hasPrimitiveValue()) {
value = primitiveValueToObject(property.getPrimitiveValue());
res = collection;
} else {
throw new IllegalArgumentException("Invalid property " + property);
res = CoreUtils.primitiveValueToObject(property.getPrimitiveValue());
}
return value;
return res;
}
private static String firstValidEntityKey(final Class<?> entityTypeRef) {

View File

@ -0,0 +1,93 @@
<?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>pojogen-maven-plugin-v3test</artifactId>
<groupId>org.apache.olingo</groupId>
<version>@project.version@</version>
<name>${project.artifactId}</name>
<description>A simple IT verifying the basic use case of pojogen-man-plugin.</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<artifactId>pojogen-maven-plugin</artifactId>
<groupId>org.apache.olingo</groupId>
<version>@project.version@</version>
<scope>runtime</scope>
</dependency>
<dependency>
<artifactId>olingo-client-proxy</artifactId>
<groupId>org.apache.olingo</groupId>
<version>@project.version@</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>@project.groupId@</groupId>
<artifactId>pojogen-maven-plugin</artifactId>
<version>@project.version@</version>
<executions>
<execution>
<configuration>
<outputDirectory>${project.build.directory}/generated-sources</outputDirectory>
<serviceRootURL>http://localhost:9080/stub/StaticService/V30/PrimitiveKeys.svc</serviceRootURL>
<basePackage>org.apache.olingo.fit.proxy.v3.primitivekeys</basePackage>
</configuration>
<id>v3pojoGen</id>
<phase>generate-sources</phase>
<goals>
<goal>v3pojoGen</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,20 @@
/**
* 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.
*/
File basepkg = new File( basedir, "target/generated-sources/ojc-plugin/org/apache/olingo/fit/proxy/v3" );
assert basepkg.isDirectory() && basepkg.listFiles().length>0;

View File

@ -83,6 +83,7 @@ import org.apache.olingo.commons.core.data.AtomEntityImpl;
import org.apache.olingo.commons.core.data.AtomPropertyImpl;
import org.apache.olingo.commons.core.data.AtomSerializer;
import org.apache.olingo.commons.core.data.JSONEntityImpl;
import org.apache.olingo.commons.core.data.JSONPropertyImpl;
import org.apache.olingo.commons.core.data.NullValueImpl;
import org.apache.olingo.commons.core.data.PrimitiveValueImpl;
import org.apache.olingo.fit.metadata.EntityType;
@ -209,6 +210,50 @@ public abstract class AbstractServices {
}
}
// ----------------------------------------------
// just for non nullable property test into PropertyTestITCase
// ----------------------------------------------
@PATCH
@Path("/Driver('2')")
public Response patchDriver() {
return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(version), new Exception("Non nullable properties"));
}
@GET
@Path("/StoredPIs(1000)")
public Response getStoredPI(@Context UriInfo uriInfo) {
final JSONEntityImpl entity = new JSONEntityImpl();
entity.setType("Microsoft.Test.OData.Services.ODataWCFService.StoredPI");
final Property id = new JSONPropertyImpl();
id.setType("Edm.Int32");
id.setName("StoredPIID");
id.setValue(new PrimitiveValueImpl("1000"));
entity.getProperties().add(id);
final Link edit = new LinkImpl();
edit.setHref(uriInfo.getRequestUri().toASCIIString());
edit.setRel("edit");
edit.setTitle("StoredPI");
entity.setEditLink(edit);
final ByteArrayOutputStream content = new ByteArrayOutputStream();
final OutputStreamWriter writer = new OutputStreamWriter(content, Constants.ENCODING);
try {
mapper.writeValue(writer, new JSONEntryContainer(null, null, entity));
return xml.createResponse(new ByteArrayInputStream(content.toByteArray()), null, Accept.JSON_FULLMETA);
} catch (Exception e) {
LOG.error("While creating StoredPI", e);
return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(version),e);
}
}
@PATCH
@Path("/StoredPIs(1000)")
public Response patchStoredPI() {
// just for non nullable property test into PropertyTestITCase
return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(version), new Exception("Non nullable properties"));
}
// ----------------------------------------------
protected Response bodyPartRequest(final MimeBodyPart body) throws Exception {
return bodyPartRequest(body, Collections.<String, String>emptyMap());
}
@ -420,7 +465,7 @@ public abstract class AbstractServices {
} else {
final ResWrap<JSONEntityImpl> jcont = mapper.readValue(IOUtils.toInputStream(changes, Constants.ENCODING),
new TypeReference<JSONEntityImpl>() {
});
});
entryChanges = dataBinder.toAtomEntity(jcont.getPayload());
}
@ -607,8 +652,8 @@ public abstract class AbstractServices {
} else {
final ResWrap<JSONEntityImpl> jcontainer =
mapper.readValue(IOUtils.toInputStream(entity, Constants.ENCODING),
new TypeReference<JSONEntityImpl>() {
});
new TypeReference<JSONEntityImpl>() {
});
entry = dataBinder.toAtomEntity(jcontainer.getPayload());
@ -635,7 +680,7 @@ public abstract class AbstractServices {
ResWrap<AtomEntityImpl> result = atomDeserializer.read(serialization, AtomEntityImpl.class);
result = new ResWrap<AtomEntityImpl>(
URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX)
+ entitySetName + Constants.get(version, ConstantKey.ODATA_METADATA_ENTITY_SUFFIX)),
+ entitySetName + Constants.get(version, ConstantKey.ODATA_METADATA_ENTITY_SUFFIX)),
null, result.getPayload());
final String path = Commons.getEntityBasePath(entitySetName, entityKey);
@ -697,7 +742,7 @@ public abstract class AbstractServices {
final FSManager fsManager = FSManager.instance(version);
fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
fsManager.getAbsolutePath(Commons.getEntityBasePath("Person", entityId) + Constants.get(version,
ConstantKey.ENTITY), Accept.ATOM));
ConstantKey.ENTITY), Accept.ATOM));
return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
} catch (Exception e) {
@ -749,9 +794,9 @@ public abstract class AbstractServices {
final Long newSalary = Long.valueOf(salaryMatcher.group(1)) + n;
newContent = newContent.
replaceAll("\"Salary\":" + salaryMatcher.group(1) + ",",
"\"Salary\":" + newSalary + ",").
"\"Salary\":" + newSalary + ",").
replaceAll("\\<d:Salary m:type=\"Edm.Int32\"\\>" + salaryMatcher.group(1) + "</d:Salary\\>",
"<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
"<d:Salary m:type=\"Edm.Int32\">" + newSalary + "</d:Salary>");
}
FSManager.instance(version).putInMemory(IOUtils.toInputStream(newContent, Constants.ENCODING),
@ -790,7 +835,7 @@ public abstract class AbstractServices {
final FSManager fsManager = FSManager.instance(version);
fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
fsManager.getAbsolutePath(Commons.getEntityBasePath("Product", entityId) + Constants.get(version,
ConstantKey.ENTITY), Accept.ATOM));
ConstantKey.ENTITY), Accept.ATOM));
return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
} catch (Exception e) {
@ -826,7 +871,7 @@ public abstract class AbstractServices {
final FSManager fsManager = FSManager.instance(version);
fsManager.putInMemory(xml.writeEntity(Accept.ATOM, container),
fsManager.getAbsolutePath(Commons.getEntityBasePath("ComputerDetail", entityId) + Constants.get(version,
ConstantKey.ENTITY), Accept.ATOM));
ConstantKey.ENTITY), Accept.ATOM));
return utils.getValue().createResponse(null, null, null, utils.getKey(), Response.Status.NO_CONTENT);
} catch (Exception e) {
@ -971,7 +1016,7 @@ public abstract class AbstractServices {
} else {
mapper.writeValue(
writer, new JSONFeedContainer(container.getContextURL(), container.getMetadataETag(),
dataBinder.toJSONEntitySet(container.getPayload())));
dataBinder.toJSONEntitySet(container.getPayload())));
}
return xml.createResponse(
@ -1696,8 +1741,8 @@ public abstract class AbstractServices {
mapper.writeValue(
writer,
new JSONFeedContainer(container.getContextURL(),
container.getMetadataETag(),
dataBinder.toJSONEntitySet((AtomEntitySetImpl) container.getPayload())));
container.getMetadataETag(),
dataBinder.toJSONEntitySet((AtomEntitySetImpl) container.getPayload())));
}
} else {
final ResWrap<Entity> container =
@ -1710,8 +1755,8 @@ public abstract class AbstractServices {
mapper.writeValue(
writer,
new JSONEntryContainer(container.getContextURL(),
container.getMetadataETag(),
dataBinder.toJSONEntity((AtomEntityImpl) container.getPayload())));
container.getMetadataETag(),
dataBinder.toJSONEntity((AtomEntityImpl) container.getPayload())));
}
}
@ -1781,9 +1826,9 @@ public abstract class AbstractServices {
final ResWrap<AtomPropertyImpl> container = new ResWrap<AtomPropertyImpl>(
URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX)
+ (version.compareTo(ODataServiceVersion.V40) >= 0
? entitySetName + "(" + entityId + ")/" + path
: property.getType())),
+ (version.compareTo(ODataServiceVersion.V40) >= 0
? entitySetName + "(" + entityId + ")/" + path
: property.getType())),
entryContainer.getMetadataETag(),
property);
@ -1791,9 +1836,9 @@ public abstract class AbstractServices {
null,
searchForValue
? IOUtils.toInputStream(
container.getPayload().getValue() == null || container.getPayload().getValue().isNull()
? StringUtils.EMPTY
: container.getPayload().getValue().asPrimitive().get(), Constants.ENCODING)
container.getPayload().getValue() == null || container.getPayload().getValue().isNull()
? StringUtils.EMPTY
: container.getPayload().getValue().asPrimitive().get(), Constants.ENCODING)
: utils.writeProperty(acceptType, container),
Commons.getETag(Commons.getEntityBasePath(entitySetName, entityId), version),
acceptType);

View File

@ -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.fit;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.olingo.fit.utils.Accept;
import org.apache.olingo.fit.utils.FSManager;
import org.springframework.stereotype.Service;
@Service
@Path("/V30/PrimitiveKeys.svc")
public class V3PrimitiveKeys extends V3Services {
public V3PrimitiveKeys() throws Exception {
super();
}
/**
* Provide sample large metadata.
*
* @return metadata.
*/
@GET
@Path("/$metadata")
@Produces(MediaType.APPLICATION_XML)
@Override
public Response getMetadata() {
try {
return xml.createResponse(
null, FSManager.instance(version).readFile("primitiveKeysMetadata", Accept.XML), null, Accept.XML);
} catch (Exception e) {
return xml.createFaultResponse(Accept.XML.toString(version), e);
}
}
}

View File

@ -0,0 +1,38 @@
<?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.
-->
<entry xml:base="http://localhost:8080/DefaultService.svc/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<id>http://localhost:8080/DefaultService.svc/Driver('2')</id>
<category term="Microsoft.Test.OData.Services.AstoriaDefaultService.Driver" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<link rel="edit" title="Driver" href="Driver('2')" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/License" type="application/atom+xml;type=entry" title="License" href="Driver('2')/License" />
<title />
<updated>2014-05-13T14:07:58Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:Name>2</d:Name>
<d:BirthDate m:type="Edm.DateTime">2012-07-03T05:54:46.6217744</d:BirthDate>
</m:properties>
</content>
</entry>

View File

@ -0,0 +1,147 @@
<?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.
-->
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
<edmx:DataServices m:DataServiceVersion="3.0" m:MaxDataServiceVersion="3.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<Schema Namespace="Microsoft.Test.OData.Services.PrimitiveKeysService" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
<EntityType Name="EdmBinary">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Binary" Nullable="false" />
</EntityType>
<EntityType Name="EdmBoolean">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Boolean" Nullable="false" />
</EntityType>
<EntityType Name="EdmByte">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Byte" Nullable="false" />
</EntityType>
<EntityType Name="EdmDateTime">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.DateTime" Nullable="false" />
</EntityType>
<EntityType Name="EdmDecimal">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Decimal" Nullable="false" />
</EntityType>
<EntityType Name="EdmDouble">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Double" Nullable="false" />
</EntityType>
<EntityType Name="EdmSingle">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Single" Nullable="false" />
</EntityType>
<EntityType Name="EdmGuid">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Guid" Nullable="false" />
</EntityType>
<EntityType Name="EdmInt16">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Int16" Nullable="false" />
</EntityType>
<EntityType Name="EdmInt32">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false" />
</EntityType>
<EntityType Name="EdmInt64">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Int64" Nullable="false" />
</EntityType>
<EntityType Name="EdmString">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.String" Nullable="false" />
</EntityType>
<EntityType Name="EdmTime">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Time" Nullable="false" />
</EntityType>
<EntityType Name="EdmDateTimeOffset">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.DateTimeOffset" Nullable="false" />
</EntityType>
<EntityType Name="Folder">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false" />
<Property Name="Name" Type="Edm.String" />
<NavigationProperty Name="Parent" Relationship="Microsoft.Test.OData.Services.PrimitiveKeysService.Folder_Parent" ToRole="Parent" FromRole="Folder" />
</EntityType>
<Association Name="Folder_Parent">
<End Type="Microsoft.Test.OData.Services.PrimitiveKeysService.Folder" Role="Parent" Multiplicity="0..1" />
<End Type="Microsoft.Test.OData.Services.PrimitiveKeysService.Folder" Role="Folder" Multiplicity="*" />
</Association>
<EntityContainer Name="TestContext" m:IsDefaultEntityContainer="true">
<EntitySet Name="EdmBinarySet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmBinary" />
<EntitySet Name="EdmBooleanSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmBoolean" />
<EntitySet Name="EdmByteSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmByte" />
<EntitySet Name="EdmDateTimeSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmDateTime" />
<EntitySet Name="EdmDecimalSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmDecimal" />
<EntitySet Name="EdmDoubleSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmDouble" />
<EntitySet Name="EdmSingleSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmSingle" />
<EntitySet Name="EdmGuidSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmGuid" />
<EntitySet Name="EdmInt16Set" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmInt16" />
<EntitySet Name="EdmInt32Set" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmInt32" />
<EntitySet Name="EdmInt64Set" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmInt64" />
<EntitySet Name="EdmStringSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmString" />
<EntitySet Name="EdmTimeSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmTime" />
<EntitySet Name="EdmDateTimeOffsetSet" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.EdmDateTimeOffset" />
<EntitySet Name="Folders" EntityType="Microsoft.Test.OData.Services.PrimitiveKeysService.Folder" />
<AssociationSet Name="Folder_Parent" Association="Microsoft.Test.OData.Services.PrimitiveKeysService.Folder_Parent">
<End Role="Folder" EntitySet="Folders" />
<End Role="Parent" EntitySet="Folders" />
</AssociationSet>
</EntityContainer>
<Annotations Target="Microsoft.Test.OData.Services.PrimitiveKeysService.TestContext">
<ValueAnnotation Term="Com.Microsoft.Data.Services.Conventions.V1.UrlConventions" String="KeyAsSegment" />
</Annotations>
</Schema>
</edmx:DataServices>
</edmx:Edmx>

View File

@ -42,6 +42,7 @@
<bean class="org.apache.olingo.fit.V3Services"/>
<bean class="org.apache.olingo.fit.V3KeyAsSegment"/>
<bean class="org.apache.olingo.fit.V3ActionOverloading"/>
<bean class="org.apache.olingo.fit.V3PrimitiveKeys"/>
<bean class="org.apache.olingo.fit.V3OpenType"/>
<bean class="org.apache.olingo.fit.V4Services"/>
<bean class="org.apache.olingo.fit.V4KeyAsSegment"/>

View File

@ -55,6 +55,8 @@ public abstract class AbstractTestITCase {
protected static String testStaticServiceRootURL;
protected static String testPrimitiveKeysServiceRootURL;
protected static String testKeyAsSegmentServiceRootURL;
protected static String testActionOverloadingServiceRootURL;
@ -74,6 +76,7 @@ public abstract class AbstractTestITCase {
@BeforeClass
public static void setUpODataServiceRoot() throws IOException {
testStaticServiceRootURL = "http://localhost:9080/stub/StaticService/V30/Static.svc";
testPrimitiveKeysServiceRootURL = "http://localhost:9080/stub/StaticService/V30/PrimitiveKeys.svc";
testKeyAsSegmentServiceRootURL = "http://localhost:9080/stub/StaticService/V30/KeyAsSegment.svc";
testActionOverloadingServiceRootURL = "http://localhost:9080/stub/StaticService/V30/ActionOverloading.svc";
testOpenTypeServiceRootURL = "http://localhost:9080/stub/StaticService/V30/OpenType.svc";

View File

@ -0,0 +1,56 @@
/*
* 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.fit.proxy.v3;
import org.apache.olingo.ext.proxy.EntityContainerFactory;
import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.Driver;
import org.apache.olingo.fit.proxy.v3.staticservice.microsoft.test.odata.services.astoriadefaultservice.types.Order;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import org.junit.Test;
/**
* This is the unit test class to check actions overloading.
*/
public class PropertyTestITCase extends AbstractTestITCase {
@Test
public void nullNullableProperty() {
Order order = container.getOrder().get(-8);
order.setCustomerId(null);
container.flush();
assertNull(container.getOrder().get(-8).getCustomerId());
}
@Test
public void nullNonNullableProperty() {
Driver driver = container.getDriver().get("2");
driver.setBirthDate(null);
try {
container.flush();
fail();
} catch (IllegalStateException e) {
// ignore and detach all
EntityContainerFactory.getContext().detachAll();
}
}
}

View File

@ -0,0 +1,56 @@
/*
* 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.fit.proxy.v4;
import org.apache.olingo.ext.proxy.EntityContainerFactory;
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.Customer;
import org.apache.olingo.fit.proxy.v4.staticservice.microsoft.test.odata.services.odatawcfservice.types.StoredPI;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import org.junit.Test;
/**
* This is the unit test class to check actions overloading.
*/
public class PropertyTestITCase extends AbstractTestITCase {
@Test
public void nullNullableProperty() {
Customer customer = container.getCustomers().get(1);
customer.setFirstName(null);
container.flush();
assertNull(container.getCustomers().get(1).getFirstName());
}
@Test
public void nullNonNullableProperty() {
final StoredPI storedPI = container.getStoredPIs().get(1000);
storedPI.setPIName(null);
try {
container.flush();
fail();
} catch (IllegalStateException e) {
// ignore and detach all
EntityContainerFactory.getContext().detachAll();
}
}
}

View File

@ -127,7 +127,7 @@ public class PrimitiveValueTest extends AbstractTest {
setText(primitive).build();
assertEquals(EdmPrimitiveTypeKind.Time, value.asPrimitive().getTypeKind());
// performed cast to improve the check
assertEquals(primitive, value.asPrimitive().toCastValue(Duration.class).toString());
assertEquals("-780670.5063807", value.asPrimitive().toCastValue(BigDecimal.class).toString());
}
@Test

View File

@ -25,7 +25,7 @@ import java.util.regex.Pattern;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
public final class EdmDuration extends SingletonPrimitiveType {
public class EdmDuration extends SingletonPrimitiveType {
private static final Pattern PATTERN = Pattern.compile(
"[-+]?P(?:(\\p{Digit}+)D)?(?:T(?:(\\p{Digit}+)H)?(?:(\\p{Digit}+)M)?"
@ -81,6 +81,7 @@ public final class EdmDuration extends SingletonPrimitiveType {
throw new EdmPrimitiveTypeException(
"EdmPrimitiveTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType), e");
} catch (final ClassCastException e) {
e.printStackTrace();
throw new EdmPrimitiveTypeException(
"EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType), e");
}

View File

@ -18,15 +18,10 @@
*/
package org.apache.olingo.commons.core.edm.primitivetype;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
/**
* Implementation of the EDM primitive type Time.
*/
public final class EdmTime extends SingletonPrimitiveType {
public final class EdmTime extends EdmDuration {
private static final EdmTime INSTANCE = new EdmTime();
@ -38,45 +33,4 @@ public final class EdmTime extends SingletonPrimitiveType {
uriPrefix = "time'";
uriSuffix = "'";
}
@Override
public Class<?> getDefaultType() {
return Duration.class;
}
@Override
protected <T> T internalValueOfString(final String value,
final Boolean isNullable, final Integer maxLength, final Integer precision,
final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
Duration duration = null;
try {
final DatatypeFactory dtFactory = DatatypeFactory.newInstance();
duration = dtFactory.newDuration(value);
} catch (Exception e) {
throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)", e);
}
if (returnType.isAssignableFrom(Duration.class)) {
return returnType.cast(duration);
} else {
throw new EdmPrimitiveTypeException(
"EdmPrimitiveTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value, returnType)");
}
}
@Override
protected <T> String internalValueToString(final T value,
final Boolean isNullable, final Integer maxLength, final Integer precision,
final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
if (value instanceof Duration) {
final Duration duration = (Duration) value;
return duration.toString();
} else {
throw new EdmPrimitiveTypeException(
"EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass())");
}
}
}