values);
+ public abstract ETagHelper createETagHelper();
}
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataHttpHandler.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataHttpHandler.java
index 37002916b..20ed77eec 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataHttpHandler.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/ODataHttpHandler.java
@@ -21,6 +21,7 @@ package org.apache.olingo.server.api;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.olingo.server.api.etag.CustomETagSupport;
import org.apache.olingo.server.api.processor.Processor;
import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/CustomETagSupport.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/etag/CustomETagSupport.java
similarity index 98%
rename from lib/server-api/src/main/java/org/apache/olingo/server/api/CustomETagSupport.java
rename to lib/server-api/src/main/java/org/apache/olingo/server/api/etag/CustomETagSupport.java
index 5e4f50003..c0dba7817 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/CustomETagSupport.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/etag/CustomETagSupport.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.olingo.server.api;
+package org.apache.olingo.server.api.etag;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/etag/ETagHelper.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/etag/ETagHelper.java
new file mode 100644
index 000000000..ae8b0e292
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/etag/ETagHelper.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.api.etag;
+
+import java.util.Collection;
+
+/**
+ * Used for ETag-related tasks.
+ */
+public interface ETagHelper {
+ /**
+ * Checks the preconditions of a read request with a given ETag value
+ * against the If-Match and If-None-Match HTTP headers.
+ * If the given ETag value is not matched by the ETag information in the If-Match headers,
+ * and there are ETags in the headers to be matched, a "Precondition Failed" exception is
+ * thrown.
+ * If the given ETag value is matched by the ETag information in the If-None-Match headers,
+ * true
is returned, and applications are supposed to return an empty response
+ * with a "Not Modified" status code and the ETag header, false
otherwise.
+ * All matching uses weak comparison as described in
+ * RFC 7232, section 2.3.2.
+ * This method does not nothing and returns false
if the ETag value is
+ * null
.
+ * @param eTag the ETag value to match
+ * @param ifMatchHeaders the If-Match header values
+ * @param ifNoneMatchHeaders the If-None-Match header values
+ * @return whether a "Not Modified" response should be used
+ */
+ public boolean checkReadPreconditions(String eTag,
+ Collection ifMatchHeaders, Collection ifNoneMatchHeaders)
+ throws PreconditionRequiredException;
+
+ /**
+ * Checks the preconditions of a change request (with HTTP methods PUT, PATCH, or DELETE)
+ * with a given ETag value against the If-Match and If-None-Match HTTP headers.
+ * If the given ETag value is not matched by the ETag information in the If-Match headers,
+ * and there are ETags in the headers to be matched, or
+ * if the given ETag value is matched by the ETag information in the If-None-Match headers,
+ * a "Precondition Failed" exception is thrown.
+ * All matching uses weak comparison as described in
+ * RFC 7232, section 2.3.2.
+ * This method does not nothing if the ETag value is null
.
+ * @param eTag the ETag value to match
+ * @param ifMatchHeaders the If-Match header values
+ * @param ifNoneMatchHeaders the If-None-Match header values
+ */
+ public void checkChangePreconditions(String eTag,
+ Collection ifMatchHeaders, Collection ifNoneMatchHeaders)
+ throws PreconditionRequiredException;
+}
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/PreconditionRequiredException.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/etag/PreconditionRequiredException.java
similarity index 94%
rename from lib/server-core/src/main/java/org/apache/olingo/server/core/PreconditionRequiredException.java
rename to lib/server-api/src/main/java/org/apache/olingo/server/api/etag/PreconditionRequiredException.java
index 25ba11771..b49298fbc 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/PreconditionRequiredException.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/etag/PreconditionRequiredException.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.olingo.server.core;
+package org.apache.olingo.server.api.etag;
import org.apache.olingo.server.api.ODataLibraryException;
@@ -25,7 +25,9 @@ public class PreconditionRequiredException extends ODataLibraryException {
public static enum MessageKeys implements MessageKey {
/** no parameter */
- MISSING_HEADER,
+ MISSING_HEADER,
+ /** no parameter */
+ FAILED,
/** no parameter */
INVALID_URI;
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataDispatcher.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataDispatcher.java
index 30edc5a18..d05a98bb4 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataDispatcher.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataDispatcher.java
@@ -33,6 +33,7 @@ import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
+import org.apache.olingo.server.api.etag.PreconditionRequiredException;
import org.apache.olingo.server.api.processor.ActionComplexCollectionProcessor;
import org.apache.olingo.server.api.processor.ActionComplexProcessor;
import org.apache.olingo.server.api.processor.ActionEntityCollectionProcessor;
@@ -67,6 +68,7 @@ import org.apache.olingo.server.api.uri.UriResourcePartTyped;
import org.apache.olingo.server.api.uri.UriResourcePrimitiveProperty;
import org.apache.olingo.server.api.uri.UriResourceProperty;
import org.apache.olingo.server.core.batchhandler.BatchHandler;
+import org.apache.olingo.server.core.etag.PreconditionsValidator;
public class ODataDispatcher {
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataExceptionHelper.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataExceptionHelper.java
index e91e9e2d5..664b50aed 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataExceptionHelper.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataExceptionHelper.java
@@ -26,6 +26,7 @@ import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ODataLibraryException.ODataErrorMessage;
import org.apache.olingo.server.api.deserializer.DeserializerException;
+import org.apache.olingo.server.api.etag.PreconditionRequiredException;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.core.uri.parser.UriParserException;
import org.apache.olingo.server.core.uri.parser.UriParserSemanticException;
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
index b266549a1..82313f54f 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHandler.java
@@ -26,7 +26,6 @@ import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod;
-import org.apache.olingo.server.api.CustomETagSupport;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataLibraryException;
@@ -35,6 +34,8 @@ import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.deserializer.DeserializerException;
+import org.apache.olingo.server.api.etag.CustomETagSupport;
+import org.apache.olingo.server.api.etag.PreconditionRequiredException;
import org.apache.olingo.server.api.processor.DefaultProcessor;
import org.apache.olingo.server.api.processor.ErrorProcessor;
import org.apache.olingo.server.api.processor.Processor;
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
index 4fb66407a..5563f1b64 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataHttpHandlerImpl.java
@@ -33,7 +33,6 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod;
-import org.apache.olingo.server.api.CustomETagSupport;
import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataHttpHandler;
@@ -41,6 +40,7 @@ import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.etag.CustomETagSupport;
import org.apache.olingo.server.api.processor.Processor;
import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
import org.apache.olingo.server.api.serializer.SerializerException;
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
index e3cbd6d22..5c5229f55 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
@@ -18,8 +18,6 @@
*/
package org.apache.olingo.server.core;
-import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
@@ -27,7 +25,6 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
-import org.apache.olingo.server.api.ETagInformation;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataHttpHandler;
import org.apache.olingo.server.api.ServiceMetadata;
@@ -35,12 +32,14 @@ import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.deserializer.FixedFormatDeserializer;
import org.apache.olingo.server.api.deserializer.ODataDeserializer;
import org.apache.olingo.server.api.edmx.EdmxReference;
+import org.apache.olingo.server.api.etag.ETagHelper;
import org.apache.olingo.server.api.serializer.FixedFormatSerializer;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriHelper;
import org.apache.olingo.server.core.deserializer.FixedFormatDeserializerImpl;
import org.apache.olingo.server.core.deserializer.json.ODataJsonDeserializer;
+import org.apache.olingo.server.core.etag.ETagHelperImpl;
import org.apache.olingo.server.core.serializer.FixedFormatSerializerImpl;
import org.apache.olingo.server.core.serializer.json.ODataJsonSerializer;
import org.apache.olingo.server.core.serializer.xml.ODataXmlSerializerImpl;
@@ -96,21 +95,20 @@ public class ODataImpl extends OData {
@Override
public ODataDeserializer createDeserializer(final ODataFormat format) throws DeserializerException {
- ODataDeserializer serializer;
+ ODataDeserializer deserializer;
switch (format) {
case JSON:
case JSON_NO_METADATA:
case JSON_FULL_METADATA:
- serializer = new ODataJsonDeserializer();
+ deserializer = new ODataJsonDeserializer();
break;
case XML:
- // We do not support xml deserialization right now so this mus lead to an error
+ // We do not support XML deserialization right now so this must lead to an error.
default:
throw new DeserializerException("Unsupported format: " + format,
- SerializerException.MessageKeys.UNSUPPORTED_FORMAT, format.toString());
+ DeserializerException.MessageKeys.UNSUPPORTED_FORMAT, format.toString());
}
-
- return serializer;
+ return deserializer;
}
@Override
@@ -119,10 +117,7 @@ public class ODataImpl extends OData {
}
@Override
- public ETagInformation createETagInformation(final Collection values) {
- final Collection eTags = ETagParser.parse(values);
- final boolean isAll = eTags.size() == 1 && eTags.iterator().next().equals("*");
- return new ETagInformation(isAll,
- isAll ? Collections. emptySet() : Collections.unmodifiableCollection(eTags));
+ public ETagHelper createETagHelper() {
+ return new ETagHelperImpl();
}
}
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/etag/ETagHelperImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/etag/ETagHelperImpl.java
new file mode 100644
index 000000000..1d8c6d63d
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/etag/ETagHelperImpl.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.core.etag;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.olingo.server.api.etag.ETagHelper;
+import org.apache.olingo.server.api.etag.PreconditionRequiredException;
+
+public class ETagHelperImpl implements ETagHelper {
+
+ @Override
+ public boolean checkReadPreconditions(final String eTag,
+ final Collection ifMatchHeaders, final Collection ifNoneMatchHeaders)
+ throws PreconditionRequiredException {
+ if (eTag != null) {
+ final ETagInformation ifMatch = createETagInformation(ifMatchHeaders);
+ if (!ifMatch.isMatchedBy(eTag) && !ifMatch.getETags().isEmpty()) {
+ throw new PreconditionRequiredException("The If-Match precondition is not fulfilled.",
+ PreconditionRequiredException.MessageKeys.FAILED);
+ }
+ return createETagInformation(ifNoneMatchHeaders).isMatchedBy(eTag);
+ }
+ return false;
+ }
+
+ @Override
+ public void checkChangePreconditions(final String eTag,
+ final Collection ifMatchHeaders, final Collection ifNoneMatchHeaders)
+ throws PreconditionRequiredException {
+ if (eTag != null) {
+ final ETagInformation ifMatch = createETagInformation(ifMatchHeaders);
+ final ETagInformation ifNoneMatch = createETagInformation(ifNoneMatchHeaders);
+ if (!ifMatch.isMatchedBy(eTag) && !ifMatch.getETags().isEmpty()
+ || ifNoneMatch.isMatchedBy(eTag)) {
+ throw new PreconditionRequiredException("The preconditions are not fulfilled.",
+ PreconditionRequiredException.MessageKeys.FAILED);
+ }
+ }
+ }
+
+ /**
+ * Creates ETag information from the values of a HTTP header
+ * containing a list of entity tags or a single star character, i.e.,
+ * If-Match
and If-None-Match
.
+ * @param values the collection of header values
+ * @return an {@link ETagInformation} instance
+ */
+ protected ETagInformation createETagInformation(final Collection values) {
+ final Collection eTags = ETagParser.parse(values);
+ final boolean isAll = eTags.size() == 1 && eTags.iterator().next().equals("*");
+ return new ETagInformation(isAll,
+ isAll ? Collections. emptySet() : Collections.unmodifiableCollection(eTags));
+ }
+}
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/ETagInformation.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/etag/ETagInformation.java
similarity index 98%
rename from lib/server-api/src/main/java/org/apache/olingo/server/api/ETagInformation.java
rename to lib/server-core/src/main/java/org/apache/olingo/server/core/etag/ETagInformation.java
index fa65722be..03310eca7 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/ETagInformation.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/etag/ETagInformation.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.olingo.server.api;
+package org.apache.olingo.server.core.etag;
import java.util.Collection;
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ETagParser.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/etag/ETagParser.java
similarity index 98%
rename from lib/server-core/src/main/java/org/apache/olingo/server/core/ETagParser.java
rename to lib/server-core/src/main/java/org/apache/olingo/server/core/etag/ETagParser.java
index 20332f62a..b8534dd2a 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ETagParser.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/etag/ETagParser.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.olingo.server.core;
+package org.apache.olingo.server.core.etag;
import java.util.Collection;
import java.util.Collections;
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/PreconditionsValidator.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/etag/PreconditionsValidator.java
similarity index 96%
rename from lib/server-core/src/main/java/org/apache/olingo/server/core/PreconditionsValidator.java
rename to lib/server-core/src/main/java/org/apache/olingo/server/core/etag/PreconditionsValidator.java
index 490acc1ec..3adf8af77 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/PreconditionsValidator.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/etag/PreconditionsValidator.java
@@ -16,12 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.olingo.server.core;
+package org.apache.olingo.server.core.etag;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
import org.apache.olingo.commons.api.edm.EdmFunctionImport;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
-import org.apache.olingo.server.api.CustomETagSupport;
+import org.apache.olingo.server.api.etag.CustomETagSupport;
+import org.apache.olingo.server.api.etag.PreconditionRequiredException;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/ETagParserTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/etag/ETagParserTest.java
similarity index 66%
rename from lib/server-core/src/test/java/org/apache/olingo/server/core/ETagParserTest.java
rename to lib/server-core/src/test/java/org/apache/olingo/server/core/etag/ETagParserTest.java
index 7931b2bcd..059d53d11 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/ETagParserTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/etag/ETagParserTest.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.olingo.server.core;
+package org.apache.olingo.server.core.etag;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.hasItems;
@@ -28,17 +28,15 @@ import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.Collections;
-import org.apache.olingo.server.api.ETagInformation;
-import org.apache.olingo.server.api.OData;
import org.junit.Test;
public class ETagParserTest {
- private static final OData odata = OData.newInstance();
+ private static final ETagHelperImpl eTagHelper = new ETagHelperImpl();
@Test
public void empty() {
- final ETagInformation eTagInformation = odata.createETagInformation(null);
+ final ETagInformation eTagInformation = eTagHelper.createETagInformation(null);
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertTrue(eTagInformation.getETags().isEmpty());
@@ -46,7 +44,7 @@ public class ETagParserTest {
@Test
public void loneStar() {
- final ETagInformation eTagInformation = odata.createETagInformation(Collections.singleton("*"));
+ final ETagInformation eTagInformation = eTagHelper.createETagInformation(Collections.singleton("*"));
assertTrue(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertTrue(eTagInformation.getETags().isEmpty());
@@ -54,7 +52,7 @@ public class ETagParserTest {
@Test
public void starWins() {
- final ETagInformation eTagInformation = odata.createETagInformation(Arrays.asList("\"ETag\"", "*"));
+ final ETagInformation eTagInformation = eTagHelper.createETagInformation(Arrays.asList("\"ETag\"", "*"));
assertTrue(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
assertTrue(eTagInformation.getETags().isEmpty());
@@ -62,7 +60,7 @@ public class ETagParserTest {
@Test
public void starAsEtagAndEmptyEtag() {
- final ETagInformation eTagInformation = odata.createETagInformation(
+ final ETagInformation eTagInformation = eTagHelper.createETagInformation(
Collections.singleton("\"*\", \"\""));
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
@@ -72,7 +70,7 @@ public class ETagParserTest {
@Test
public void severalEtags() {
- final ETagInformation eTagInformation = odata.createETagInformation(
+ final ETagInformation eTagInformation = eTagHelper.createETagInformation(
Arrays.asList("\"ETag1\"", "\"ETag2\",, , ,W/\"ETag3\", ,"));
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
@@ -82,7 +80,7 @@ public class ETagParserTest {
@Test
public void duplicateEtagValues() {
- final ETagInformation eTagInformation = odata.createETagInformation(
+ final ETagInformation eTagInformation = eTagHelper.createETagInformation(
Arrays.asList("\"ETag1\"", "\"ETag2\", W/\"ETag1\", \"ETag1\""));
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
@@ -92,7 +90,7 @@ public class ETagParserTest {
@Test
public void specialCharacters() {
- final ETagInformation eTagInformation = odata.createETagInformation(
+ final ETagInformation eTagInformation = eTagHelper.createETagInformation(
Collections.singleton("\"!#$%&'()*+,-./:;<=>?@[]^_`{|}~ยก\u00FF\", \"ETag2\""));
assertFalse(eTagInformation.isAll());
assertNotNull(eTagInformation.getETags());
@@ -103,7 +101,7 @@ public class ETagParserTest {
@Test
public void wrongFormat() {
- final ETagInformation eTagInformation = odata.createETagInformation(
+ final ETagInformation eTagInformation = eTagHelper.createETagInformation(
Arrays.asList("\"ETag1\", ETag2", "w/\"ETag3\"", "W//\"ETag4\"", "W/ETag5",
"\"\"ETag6\"\"", " \"ETag7\"\"ETag7\" ", "\"ETag8\" \"ETag8\"",
"\"ETag 9\"", "\"ETag10\""));
@@ -115,17 +113,17 @@ public class ETagParserTest {
@Test
public void match() {
- assertFalse(odata.createETagInformation(Collections. emptySet()).isMatchedBy("\"ETag\""));
- assertFalse(odata.createETagInformation(Collections.singleton("\"ETag\"")).isMatchedBy(null));
- assertTrue(odata.createETagInformation(Collections.singleton("\"ETag\"")).isMatchedBy("\"ETag\""));
- assertTrue(odata.createETagInformation(Collections.singleton("*")).isMatchedBy("\"ETag\""));
- assertTrue(odata.createETagInformation(Collections.singleton("\"ETag\"")).isMatchedBy("W/\"ETag\""));
- assertTrue(odata.createETagInformation(Collections.singleton("W/\"ETag\"")).isMatchedBy("\"ETag\""));
- assertFalse(odata.createETagInformation(Collections.singleton("\"ETag\"")).isMatchedBy("W/\"ETag2\""));
- assertFalse(odata.createETagInformation(Collections.singleton("W/\"ETag\"")).isMatchedBy("\"ETag2\""));
- assertTrue(odata.createETagInformation(Arrays.asList("\"ETag1\",\"ETag2\"", "\"ETag3\",\"ETag4\""))
+ assertFalse(eTagHelper.createETagInformation(Collections. emptySet()).isMatchedBy("\"ETag\""));
+ assertFalse(eTagHelper.createETagInformation(Collections.singleton("\"ETag\"")).isMatchedBy(null));
+ assertTrue(eTagHelper.createETagInformation(Collections.singleton("\"ETag\"")).isMatchedBy("\"ETag\""));
+ assertTrue(eTagHelper.createETagInformation(Collections.singleton("*")).isMatchedBy("\"ETag\""));
+ assertTrue(eTagHelper.createETagInformation(Collections.singleton("\"ETag\"")).isMatchedBy("W/\"ETag\""));
+ assertTrue(eTagHelper.createETagInformation(Collections.singleton("W/\"ETag\"")).isMatchedBy("\"ETag\""));
+ assertFalse(eTagHelper.createETagInformation(Collections.singleton("\"ETag\"")).isMatchedBy("W/\"ETag2\""));
+ assertFalse(eTagHelper.createETagInformation(Collections.singleton("W/\"ETag\"")).isMatchedBy("\"ETag2\""));
+ assertTrue(eTagHelper.createETagInformation(Arrays.asList("\"ETag1\",\"ETag2\"", "\"ETag3\",\"ETag4\""))
.isMatchedBy("\"ETag4\""));
- assertFalse(odata.createETagInformation(Arrays.asList("\"ETag1\",\"ETag2\"", "\"ETag3\",\"ETag4\""))
+ assertFalse(eTagHelper.createETagInformation(Arrays.asList("\"ETag1\",\"ETag2\"", "\"ETag3\",\"ETag4\""))
.isMatchedBy("\"ETag5\""));
}
}
\ No newline at end of file
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/ETagSupport.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/ETagSupport.java
index 901110707..09d4910c6 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/ETagSupport.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/ETagSupport.java
@@ -19,7 +19,7 @@
package org.apache.olingo.server.tecsvc;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
-import org.apache.olingo.server.api.CustomETagSupport;
+import org.apache.olingo.server.api.etag.CustomETagSupport;
public class ETagSupport implements CustomETagSupport {
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
index eaec6d002..086f69c5c 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
@@ -161,9 +161,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
.validate(edmEntitySet, deserializerResult.getEntity());
entity = dataProvider.create(edmEntitySet);
- dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, deserializerResult.getEntity(), false,
-
- true);
+ dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, deserializerResult.getEntity(), false, true);
expand = deserializerResult.getExpandTree();
}
@@ -199,7 +197,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
}
}
- checkChangePreconditions(entity.getETag(),
+ odata.createETagHelper().checkChangePreconditions(entity.getETag(),
request.getHeaders(HttpHeader.IF_MATCH),
request.getHeaders(HttpHeader.IF_NONE_MATCH));
checkRequestFormat(requestFormat);
@@ -232,7 +230,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
final EdmEntityType edmEntityType = edmEntitySet.getEntityType();
Entity entity = readEntity(uriInfo);
- checkChangePreconditions(entity.getMediaETag(),
+ odata.createETagHelper().checkChangePreconditions(entity.getMediaETag(),
request.getHeaders(HttpHeader.IF_MATCH),
request.getHeaders(HttpHeader.IF_NONE_MATCH));
checkRequestFormat(requestFormat);
@@ -251,13 +249,13 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
@Override
public void deleteEntity(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
- throws ODataApplicationException {
+ throws ODataLibraryException, ODataApplicationException {
final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo);
final Entity entity = readEntity(uriInfo);
final List resourcePaths = uriInfo.getUriResourceParts();
final boolean isValue = resourcePaths.get(resourcePaths.size() - 1) instanceof UriResourceValue;
- checkChangePreconditions(isValue ? entity.getMediaETag() : entity.getETag(),
+ odata.createETagHelper().checkChangePreconditions(isValue ? entity.getMediaETag() : entity.getETag(),
request.getHeaders(HttpHeader.IF_MATCH),
request.getHeaders(HttpHeader.IF_NONE_MATCH));
dataProvider.delete(edmEntitySet, entity);
@@ -353,9 +351,13 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
final Entity entity = readEntity(uriInfo);
- checkReadPreconditions(entity.getETag(),
+ if (odata.createETagHelper().checkReadPreconditions(entity.getETag(),
request.getHeaders(HttpHeader.IF_MATCH),
- request.getHeaders(HttpHeader.IF_NONE_MATCH));
+ request.getHeaders(HttpHeader.IF_NONE_MATCH))) {
+ response.setStatusCode(HttpStatusCode.NOT_MODIFIED.getStatusCode());
+ response.setHeader(HttpHeader.ETAG, entity.getETag());
+ return;
+ }
final ODataFormat format = ODataFormat.fromContentType(requestedContentType);
final ExpandOption expand = uriInfo.getExpandOption();
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
index 4ba708128..58b38c4bb 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
@@ -171,9 +171,13 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
final Entity entity = readEntity(uriInfo);
if (entity != null && entity.getETag() != null) {
- checkReadPreconditions(entity.getETag(),
+ if (odata.createETagHelper().checkReadPreconditions(entity.getETag(),
request.getHeaders(HttpHeader.IF_MATCH),
- request.getHeaders(HttpHeader.IF_NONE_MATCH));
+ request.getHeaders(HttpHeader.IF_NONE_MATCH))) {
+ response.setStatusCode(HttpStatusCode.NOT_MODIFIED.getStatusCode());
+ response.setHeader(HttpHeader.ETAG, entity.getETag());
+ return;
+ }
}
final Property property = entity == null ?
@@ -219,7 +223,7 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
final EdmEntitySet edmEntitySet = getEdmEntitySet(resource);
Entity entity = readEntity(uriInfo);
- checkChangePreconditions(entity.getETag(),
+ odata.createETagHelper().checkChangePreconditions(entity.getETag(),
request.getHeaders(HttpHeader.IF_MATCH),
request.getHeaders(HttpHeader.IF_NONE_MATCH));
@@ -252,13 +256,13 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
}
private void deleteProperty(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
- throws ODataApplicationException {
+ throws ODataLibraryException, ODataApplicationException {
final UriInfoResource resource = uriInfo.asUriInfoResource();
validatePath(resource);
getEdmEntitySet(uriInfo); // including checks
Entity entity = readEntity(uriInfo);
- checkChangePreconditions(entity.getETag(),
+ odata.createETagHelper().checkChangePreconditions(entity.getETag(),
request.getHeaders(HttpHeader.IF_MATCH),
request.getHeaders(HttpHeader.IF_NONE_MATCH));
@@ -397,9 +401,13 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
final Entity entity = readEntity(uriInfo);
if (entity != null && entity.getETag() != null) {
- checkReadPreconditions(entity.getETag(),
+ if (odata.createETagHelper().checkReadPreconditions(entity.getETag(),
request.getHeaders(HttpHeader.IF_MATCH),
- request.getHeaders(HttpHeader.IF_NONE_MATCH));
+ request.getHeaders(HttpHeader.IF_NONE_MATCH))) {
+ response.setStatusCode(HttpStatusCode.NOT_MODIFIED.getStatusCode());
+ response.setHeader(HttpHeader.ETAG, entity.getETag());
+ return;
+ }
}
final Property property = entity == null ?
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
index b9e32fe2a..c95091d03 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
@@ -18,7 +18,6 @@
*/
package org.apache.olingo.server.tecsvc.processor;
-import java.util.Collection;
import java.util.List;
import java.util.Locale;
@@ -32,7 +31,6 @@ import org.apache.olingo.commons.api.edm.EdmFunction;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpStatusCode;
-import org.apache.olingo.server.api.ETagInformation;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ServiceMetadata;
@@ -257,34 +255,4 @@ public abstract class TechnicalProcessor implements Processor {
HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
}
}
-
- protected void checkReadPreconditions(final String eTag,
- final Collection ifMatchHeaders, final Collection ifNoneMatchHeaders)
- throws ODataApplicationException {
- if (eTag != null) {
- final ETagInformation ifMatch = odata.createETagInformation(ifMatchHeaders);
- if (!ifMatch.isMatchedBy(eTag) && !ifMatch.getETags().isEmpty()) {
- throw new ODataApplicationException("The If-Match precondition is not fulfilled.",
- HttpStatusCode.PRECONDITION_FAILED.getStatusCode(), Locale.ROOT);
- }
- if (odata.createETagInformation(ifNoneMatchHeaders).isMatchedBy(eTag)) {
- throw new ODataApplicationException("The entity has not been modified.",
- HttpStatusCode.NOT_MODIFIED.getStatusCode(), Locale.ROOT);
- }
- }
- }
-
- protected void checkChangePreconditions(final String eTag,
- final Collection ifMatchHeaders, final Collection ifNoneMatchHeaders)
- throws ODataApplicationException {
- if (eTag != null) {
- final ETagInformation ifMatch = odata.createETagInformation(ifMatchHeaders);
- final ETagInformation ifNoneMatch = odata.createETagInformation(ifNoneMatchHeaders);
- if (!ifMatch.isMatchedBy(eTag) && !ifMatch.getETags().isEmpty()
- || ifNoneMatch.isMatchedBy(eTag)) {
- throw new ODataApplicationException("The preconditions are not fulfilled.",
- HttpStatusCode.PRECONDITION_FAILED.getStatusCode(), Locale.ROOT);
- }
- }
- }
}
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/PreconditionsValidatorTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/PreconditionsValidatorTest.java
index 033f9af15..7cab5678d 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/PreconditionsValidatorTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/PreconditionsValidatorTest.java
@@ -25,8 +25,10 @@ import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.commons.core.edm.EdmProviderImpl;
-import org.apache.olingo.server.api.CustomETagSupport;
+import org.apache.olingo.server.api.etag.CustomETagSupport;
+import org.apache.olingo.server.api.etag.PreconditionRequiredException;
import org.apache.olingo.server.api.uri.UriInfo;
+import org.apache.olingo.server.core.etag.PreconditionsValidator;
import org.apache.olingo.server.core.uri.parser.Parser;
import org.apache.olingo.server.core.uri.parser.UriParserException;
import org.apache.olingo.server.core.uri.parser.UriParserSemanticException;