OLINGO-864: Refining the Edm.Date and Edm.Time behavior not to assume GMT
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/f63bba70 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/f63bba70 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/f63bba70 Branch: refs/heads/master Commit: f63bba70ad4c63a621b5a8e8186d50c172263989 Parents: b317b90 382ec16 Author: Ramesh Reddy <[email protected]> Authored: Wed Feb 3 11:48:04 2016 -0600 Committer: Ramesh Reddy <[email protected]> Committed: Wed Feb 3 11:48:04 2016 -0600 ---------------------------------------------------------------------- .../client/AbstractParamTecSvcITCase.java | 14 ++++ .../commons/core/edm/primitivetype/EdmDate.java | 5 +- .../edm/primitivetype/EdmDateTimeOffset.java | 75 +++++++++++++------- .../core/edm/primitivetype/EdmTimeOfDay.java | 20 ++---- .../core/edm/primitivetype/EdmDateTest.java | 1 - .../primitivetype/EdmDateTimeOffsetTest.java | 9 ++- .../edm/primitivetype/EdmTimeOfDayTest.java | 23 ++++-- .../olingo/server/tecsvc/data/DataProvider.java | 6 ++ .../server/tecsvc/data/DataProviderTest.java | 14 ++++ 9 files changed, 115 insertions(+), 52 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AbstractParamTecSvcITCase.java ---------------------------------------------------------------------- diff --cc fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AbstractParamTecSvcITCase.java index d6e35a3,0000000..a4d8a67 mode 100644,000000..100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AbstractParamTecSvcITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/AbstractParamTecSvcITCase.java @@@ -1,66 -1,0 +1,80 @@@ +/* + * 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.tecsvc.client; + +import static org.hamcrest.CoreMatchers.startsWith; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; ++import java.util.TimeZone; + +import org.apache.olingo.commons.api.format.ContentType; ++import org.apache.olingo.server.tecsvc.data.DataProvider; ++import org.junit.After; ++import org.junit.Before; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public abstract class AbstractParamTecSvcITCase extends AbstractTecSvcITCase { + + @Parameterized.Parameter + public ContentType contentType; + + /** + * Returns a list of parameter arrays, in this case a list of one-element arrays + * containing the content types to be used. + */ + @Parameterized.Parameters(name = "{0}") + public static List<ContentType[]> parameters() { + return Arrays.asList(new ContentType[] { ContentType.APPLICATION_JSON }, + new ContentType[] { ContentType.APPLICATION_XML }); + } + + @Override + protected ContentType getContentType() { + return contentType; + } + + protected void assertContentType(final String content) { + assertThat(content, startsWith(contentType.toContentTypeString())); + } + + protected boolean isJson() { + return ContentType.JSON.isCompatible(contentType); + } + + protected void assertShortOrInt(final int value, final Object n) { + assertTrue(n instanceof Number); + assertEquals(value, ((Number) n).intValue()); + } ++ ++ @Before ++ public void setup() { ++ DataProvider.setDefaultTimeZone("GMT"); ++ } ++ ++ @After ++ public void teardown() { ++ DataProvider.setDefaultTimeZone(TimeZone.getDefault().getID()); ++ } +} http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java ---------------------------------------------------------------------- diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java index 3eddca0,fb3f4ad..8588a5c --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java @@@ -18,8 -18,9 +18,7 @@@ */ package org.apache.olingo.commons.core.edm.primitivetype; -import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; - import java.util.Calendar; - import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java ---------------------------------------------------------------------- diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java index a7f57d1,95b0fa5..63c2c3c --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java @@@ -18,16 -18,17 +18,17 @@@ */ package org.apache.olingo.commons.core.edm.primitivetype; + import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; + import java.sql.Time; import java.sql.Timestamp; -import java.text.DecimalFormat; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; - import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; + /** * Implementation of the EDM primitive type DateTimeOffset. */ @@@ -60,8 -68,8 +61,9 @@@ public final class EdmDateTimeOffset ex } final String timeZoneOffset = matcher.group(9) == null || matcher.group(10) == null - || matcher.group(10).matches("[-+]0+:0+") ? null : matcher.group(10); - final Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT" + timeZoneOffset)); + || matcher.group(10).matches("[-+]0+:0+") ? null : matcher.group(10); - final Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT" + timeZoneOffset)); ++ final TimeZone tz = TimeZone.getTimeZone("GMT" + ((timeZoneOffset == null) ? "" : timeZoneOffset)); ++ final Calendar dateTimeValue = Calendar.getInstance(tz); if (dateTimeValue.get(Calendar.ZONE_OFFSET) == 0 && timeZoneOffset != null) { throw new EdmPrimitiveTypeException("The literal '" + value + "' has illegal content."); } @@@ -150,19 -170,12 +165,12 @@@ @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 { + final Boolean isNullable, final Integer maxLength, final Integer precision, + final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException { - Calendar dateTimeValue; - if (value instanceof Timestamp) { - final Calendar tmp = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - tmp.setTimeInMillis(((Timestamp) value).getTime()); - dateTimeValue = createDateTime(tmp); - } else { - dateTimeValue = createDateTime(value); - } - - StringBuilder result = new StringBuilder(); + final Calendar dateTimeValue = createDateTime(value, false); + + final StringBuilder result = new StringBuilder(); final int year = dateTimeValue.get(Calendar.YEAR); appendTwoDigits(result, year / 100); appendTwoDigits(result, year % 100); @@@ -269,4 -286,49 +283,17 @@@ } } } + + /** - * Appends the given fractional seconds to the given string builder. - * - * @param result a {@link StringBuilder} - * @param fractionalSeconds fractional seconds - * @param precision the upper limit for decimal digits (optional, defaults to zero) - * @throws IllegalArgumentException if precision is not met - */ - protected static void appendFractionalSeconds(final StringBuilder result, final int fractionalSeconds, - final Integer precision) throws IllegalArgumentException { - - if (fractionalSeconds > 0) { - String formatted = NANO_FORMAT.get().format(fractionalSeconds); - int actualLength = formatted.length(); - boolean nonZeroFound = false; - for (int i = formatted.length() - 1; i >= 0 && !nonZeroFound; i--) { - if ('0' == formatted.charAt(i)) { - actualLength--; - } else { - nonZeroFound = true; - } - } - - if (precision == null || precision < actualLength) { - throw new IllegalArgumentException(); - } - - result.append('.').append(formatted.substring(0, actualLength)); - } - } - - /** + * When the Timezone information is absent on the date time types, like EdmDate, EDMTimeOfDay, EdmDateTimeOffset + * this method defines the default timezone that should be used parse and output payload. + * User should set system property "defaultTimeZoneForEdmDateTypes" to control this. The default would be + * Java VM default if not defined. + * + * @return Timezone + */ + protected static TimeZone getDefaultTimeZone() { + String tz = System.getProperty("defaultTimeZoneForEdmDateTypes"); - return (tz != null)?TimeZone.getTimeZone(tz):TimeZone.getDefault(); - } - ++ return (tz != null)?TimeZone.getTimeZone(tz):TimeZone.getDefault(); ++ } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java ---------------------------------------------------------------------- diff --cc lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java index 7595e51,3090761..06ba239 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java @@@ -18,9 -18,10 +18,8 @@@ */ package org.apache.olingo.commons.core.edm.primitivetype; -import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; - import java.sql.Timestamp; import java.util.Calendar; - import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; @@@ -112,7 -101,13 +101,8 @@@ public final class EdmTimeOfDay extend EdmDateTimeOffset.appendTwoDigits(result, dateTimeValue.get(Calendar.SECOND)); try { - EdmDateTimeOffset.appendFractionalSeconds(result, fractionalSecs, value instanceof Timestamp, precision); - if (value instanceof Timestamp) { - int fractionalSecs = ((Timestamp) value).getNanos(); - EdmDateTimeOffset.appendFractionalSeconds(result, fractionalSecs, precision); - } else { - int fractionalSecs = dateTimeValue.get(Calendar.MILLISECOND); - EdmDateTimeOffset.appendMilliseconds(result, fractionalSecs, precision); - } ++ EdmDateTimeOffset.appendFractionalSeconds(result, ++ dateTimeValue.get(Calendar.MILLISECOND), value instanceof Timestamp, precision); } catch (final IllegalArgumentException e) { throw new EdmPrimitiveTypeException("The value '" + value + "' does not match the facets' constraints.", e); } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java ---------------------------------------------------------------------- diff --cc lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java index a352703,0b51925..5f2da25 --- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java +++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java @@@ -18,10 -18,10 +18,9 @@@ */ package org.apache.olingo.commons.core.edm.primitivetype; -import org.apache.olingo.commons.api.edm.EdmPrimitiveType; -import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; -import org.junit.Test; +import static org.junit.Assert.assertEquals; - import static org.junit.Assert.assertTrue; +import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; import java.util.Date; @@@ -76,22 -74,12 +75,21 @@@ public class EdmDateTimeOffsetTest exte assertEquals("2012-02-29T23:32:03.007Z", instance.valueToString(millis, null, null, 3, null, null)); assertEquals("1969-12-31T23:59:59.9Z", instance.valueToString(-100L, null, null, 1, null, null)); assertEquals("1969-12-31T23:59:59.98Z", instance.valueToString(-20L, null, null, 2, null, null)); - + + assertEquals("2012-02-29T23:32:03.007Z", instance.valueToString(new Time(millis), null, null, 3, null, null)); + assertEquals("1969-12-31T23:59:59.9Z", instance.valueToString(new Time(-100L), null, null, 1, null, null)); + assertEquals("1969-12-31T23:59:59.98Z", instance.valueToString(new Time(-20L), null, null, 2, null, null)); + final Date date = new Date(millis); - final String time = date.toString().substring(11, 19); - assertTrue(instance.valueToString(date, null, null, 3, null, null).contains(time)); + assertEquals("2012-02-29T23:32:03.007Z", instance.valueToString(date, null, null, 3, null, null)); + Timestamp timestamp = new Timestamp(0); + timestamp.setNanos(120); + assertEquals("1970-01-01T00:00:00.00000012Z", instance.valueToString(timestamp, null, null, 8, null, null)); + expectFacetsErrorInValueToString(instance, millis, null, null, null, null, null); expectFacetsErrorInValueToString(instance, 3L, null, null, 2, null, null); + expectFacetsErrorInValueToString(instance, timestamp, null, null, 7, null, null); expectTypeErrorInValueToString(instance, 0); } @@@ -133,14 -121,7 +131,15 @@@ Long.class)); assertEquals(Long.valueOf(120L), instance.valueOfString("1970-01-01T00:00:00.12", null, null, 2, null, null, Long.class)); - + + assertEquals(new Time(120000L), instance.valueOfString("1970-01-01T00:02", null, null, null, null, null, + Time.class)); - assertEquals(new Time(12L), instance.valueOfString("1970-01-01T00:00:00.012", null, null, 3, null, null, ++ // 0L because java.sql.Time does not keep track of fraction of milliseconds ++ assertEquals(new Time(0L), instance.valueOfString("1970-01-01T00:00:00.012", null, null, 3, null, null, + Time.class)); - assertEquals(new Time(120L), instance.valueOfString("1970-01-01T00:00:00.12", null, null, 2, null, null, ++ assertEquals(new Time(0L), instance.valueOfString("1970-01-01T00:00:00.12", null, null, 2, null, null, + Time.class)); + expectFacetsErrorInValueOfString(instance, "2012-02-29T23:32:02.9Z", null, null, null, null, null); expectFacetsErrorInValueOfString(instance, "2012-02-29T23:32:02.9Z", null, null, 0, null, null); expectContentErrorInValueOfString(instance, "2012-02-29T23:32:02X"); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDayTest.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java ---------------------------------------------------------------------- diff --cc lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java index 20cbf94,878efce..5190c71 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java @@@ -512,151 -473,55 +512,157 @@@ public class DataProvider entity.getProperties().remove(entity.getProperty(MEDIA_PROPERTY_NAME)); entity.addProperty(DataCreator.createPrimitive(MEDIA_PROPERTY_NAME, media)); entity.setMediaContentType(type); + entity.setMediaETag("W/\"" + UUID.randomUUID() + "\""); + } + + public EntityCollection readFunctionEntityCollection(final EdmFunction function, final List<UriParameter> parameters, + final UriInfoResource uriInfo) throws DataProviderException { + return FunctionData.entityCollectionFunction(function.getName(), + getFunctionParameters(function, parameters, uriInfo), + data); + } + + public Entity readFunctionEntity(final EdmFunction function, final List<UriParameter> parameters, + final UriInfoResource uriInfo) throws DataProviderException { + return FunctionData.entityFunction(function.getName(), + getFunctionParameters(function, parameters, uriInfo), + data); + } + + public Property readFunctionPrimitiveComplex(final EdmFunction function, final List<UriParameter> parameters, + final UriInfoResource uriInfo) throws DataProviderException { + return FunctionData.primitiveComplexFunction(function.getName(), + getFunctionParameters(function, parameters, uriInfo), + data); + } + + private Map<String, Parameter> getFunctionParameters(final EdmFunction function, + final List<UriParameter> parameters, final UriInfoResource uriInfo) throws DataProviderException { + Map<String, Parameter> values = new HashMap<String, Parameter>(); + for (final UriParameter parameter : parameters) { + final EdmParameter edmParameter = function.getParameter(parameter.getName()); + final String text = parameter.getAlias() == null ? + parameter.getText() : + uriInfo.getValueForAlias(parameter.getAlias()); + if (text != null) { + try { + values.put(parameter.getName(), + odata.createFixedFormatDeserializer().parameter(text, edmParameter)); + } catch (final DeserializerException e) { + throw new DataProviderException("Invalid function parameter.", HttpStatusCode.BAD_REQUEST, e); + } + } + } + return values; } - public EntityCollection readFunctionEntitySet(final EdmFunction function, final List<UriParameter> parameters) + public Property processActionPrimitive(final String name, final Map<String, Parameter> actionParameters) throws DataProviderException { - return FunctionData.entityCollectionFunction(function.getName(), parameters, data); + return ActionData.primitiveAction(name, actionParameters); } - public Entity readFunctionEntity(final EdmFunction function, final List<UriParameter> parameters) + public Property processActionComplex(final String name, final Map<String, Parameter> actionParameters) throws DataProviderException { - return FunctionData.entityFunction(function.getName(), parameters, data); + return ActionData.complexAction(name, actionParameters); } - public Property readFunctionPrimitiveComplex(final EdmFunction function, final List<UriParameter> parameters) + public Property processActionComplexCollection(final String name, final Map<String, Parameter> actionParameters) throws DataProviderException { - return FunctionData.primitiveComplexFunction(function.getName(), parameters, data); + return ActionData.complexCollectionAction(name, actionParameters); } - public Property processActionPrimitive(String name, Map<String, Parameter> actionParameters) + public Property processActionPrimitiveCollection(final String name, final Map<String, Parameter> actionParameters) throws DataProviderException { - return ActionData.primitiveAction(name, actionParameters); + return ActionData.primitiveCollectionAction(name, actionParameters, odata); } - public Property processActionPrimitiveCollection(String name, Map<String, Parameter> actionParameters) + public EntityActionResult processActionEntity(final String name, final Map<String, Parameter> actionParameters) throws DataProviderException { - return ActionData.primitiveCollectionAction(name, actionParameters); + return ActionData.entityAction(name, actionParameters, data, odata, edm); } - public void setEdm(final Edm edm) { - this.edm = edm; + public EntityCollection processActionEntityCollection(final String name, + final Map<String, Parameter> actionParameters) throws DataProviderException { + return ActionData.entityCollectionAction(name, actionParameters, odata, edm); } - public void setOData(final OData odata) { - this.odata = odata; + public void createReference(final Entity entity, final EdmNavigationProperty navigationProperty, final URI entityId, + final String rawServiceRoot) throws DataProviderException { + setLink(navigationProperty, entity, getEntityByReference(entityId.toASCIIString(), rawServiceRoot)); } - public static class DataProviderException extends ODataApplicationException { - private static final long serialVersionUID = 5098059649321796156L; + public void deleteReference(final Entity entity, final EdmNavigationProperty navigationProperty, + final String entityId, final String rawServiceRoot) throws DataProviderException { - public DataProviderException(final String message, final Throwable throwable) { - super(message, HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, throwable); + if (navigationProperty.isCollection()) { + final Entity targetEntity = getEntityByReference(entityId, rawServiceRoot); + final Link navigationLink = entity.getNavigationLink(navigationProperty.getName()); + + if (navigationLink != null && navigationLink.getInlineEntitySet() != null + && navigationLink.getInlineEntitySet().getEntities().contains(targetEntity)) { + + // Remove partner single-valued navigation property + if (navigationProperty.getPartner() != null) { + final EdmNavigationProperty edmPartnerNavigationProperty = navigationProperty.getPartner(); + if (!edmPartnerNavigationProperty.isCollection() && !edmPartnerNavigationProperty.isNullable()) { + throw new DataProviderException("Navigation property must not be null", HttpStatusCode.BAD_REQUEST); + } else if (!edmPartnerNavigationProperty.isCollection()) { + removeLink(edmPartnerNavigationProperty, targetEntity); + } else if (edmPartnerNavigationProperty.isCollection() + && edmPartnerNavigationProperty.getPartner() != null) { + // Bidirectional referential constraint + final Link partnerNavigationLink = targetEntity.getNavigationLink(edmPartnerNavigationProperty.getName()); + if (partnerNavigationLink != null && partnerNavigationLink.getInlineEntitySet() != null) { + partnerNavigationLink.getInlineEntitySet().getEntities().remove(entity); + } + } + } + + // Remove target entity from collection-valued navigation property + navigationLink.getInlineEntitySet().getEntities().remove(targetEntity); + } else { + throw new DataProviderException("Entity not found", HttpStatusCode.NOT_FOUND); + } + } else { + if (navigationProperty.isNullable()) { + removeLink(navigationProperty, entity); + } else { + throw new DataProviderException("Navigation property must not be null", HttpStatusCode.BAD_REQUEST); + } } + } - public DataProviderException(final String message) { - super(message, HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); + protected Entity getEntityByReference(final String entityId, final String rawServiceRoot) + throws DataProviderException { + try { + final UriResourceEntitySet uriResource = odata.createUriHelper().parseEntityId(edm, entityId, rawServiceRoot); + final Entity targetEntity = read(uriResource.getEntitySet(), uriResource.getKeyPredicates()); + + if (targetEntity != null) { + return targetEntity; + } else { + throw new DataProviderException("Entity not found", HttpStatusCode.NOT_FOUND); + } + } catch (DeserializerException e) { + throw new DataProviderException("Invalid entity-id", HttpStatusCode.BAD_REQUEST, e); } + } - public DataProviderException(final String message, HttpStatusCode statusCode) { + public static class DataProviderException extends ODataApplicationException { + private static final long serialVersionUID = 5098059649321796156L; + + public DataProviderException(final String message, final HttpStatusCode statusCode) { super(message, statusCode.getStatusCode(), Locale.ROOT); } + + public DataProviderException(final String message, final HttpStatusCode statusCode, final Throwable throwable) { + super(message, statusCode.getStatusCode(), Locale.ROOT, throwable); + } } + ++ //CHECKSTYLE:OFF ++ public static void setDefaultTimeZone(String tz) { ++ System.setProperty("defaultTimeZoneForEdmDateTypes", tz); ++ } ++ //CHECKSTYLE:ON } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/f63bba70/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java ---------------------------------------------------------------------- diff --cc lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java index 6bd6463,c9a8e65..b2bf587 --- a/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java +++ b/lib/server-tecsvc/src/test/java/org/apache/olingo/server/tecsvc/data/DataProviderTest.java @@@ -21,6 -21,6 +21,7 @@@ package org.apache.olingo.server.tecsvc import java.util.Arrays; import java.util.Collections; import java.util.List; ++import java.util.TimeZone; import org.apache.olingo.commons.api.data.ComplexValue; import org.apache.olingo.commons.api.data.Entity; @@@ -33,7 -34,7 +34,9 @@@ import org.apache.olingo.server.api.ODa import org.apache.olingo.server.api.edmx.EdmxReference; import org.apache.olingo.server.api.uri.UriParameter; import org.apache.olingo.server.tecsvc.provider.EdmTechProvider; ++import org.junit.After; import org.junit.Assert; ++import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; @@@ -52,9 -53,9 +55,19 @@@ public class DataProviderTest private final EdmEntitySet esMixPrimCollComp = entityContainer.getEntitySet("ESMixPrimCollComp"); private final EdmEntitySet esMedia = entityContainer.getEntitySet("ESMedia"); ++ @Before ++ public void setup() { ++ DataProvider.setDefaultTimeZone("GMT"); ++ } ++ ++ @After ++ public void teardown() { ++ DataProvider.setDefaultTimeZone(TimeZone.getDefault().getID()); ++ } ++ @Test public void esAllPrimEntity() throws Exception { - final DataProvider dataProvider = new DataProvider(); + final DataProvider dataProvider = new DataProvider(oData, edm); final Entity entity = dataProvider.readAll(esAllPrim).getEntities().get(2); Assert.assertEquals(16, entity.getProperties().size()); @@@ -82,6 -83,6 +95,7 @@@ mockParameter("PropertySByte", "127"), mockParameter("PropertyString", "'First'"), mockParameter("PropertyTimeOfDay", "02:48:21")))); ++ } @Test
