[OLINGO-663] helper for conditional handling

Change-Id: I48599dc609bfb53bc2903083abe235458109e20a

Signed-off-by: Christian Amend <christian.amend@sap.com>
This commit is contained in:
Klaus Straubinger 2015-06-03 10:42:54 +02:00 committed by Christian Amend
parent b8187f5307
commit 1f286fd424
20 changed files with 218 additions and 102 deletions

View File

@ -18,7 +18,6 @@
*/
package org.apache.olingo.server.api;
import java.util.Collection;
import java.util.List;
import org.apache.olingo.commons.api.ODataRuntimeException;
@ -30,6 +29,7 @@ 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;
@ -118,11 +118,8 @@ public abstract class OData {
public abstract EdmPrimitiveType createPrimitiveTypeInstance(EdmPrimitiveTypeKind kind);
/**
* Creates ETag information from the values of a HTTP header
* containing a list of entity tags or a single star character, i.e.,
* <code>If-Match</code> and <code>If-None-Match</code>.
* @param values the collection of header values
* @return an {@link ETagInformation} instance
* Creates a new ETag helper object for performing ETag-related tasks.
* It can be used in Processor implementations.
*/
public abstract ETagInformation createETagInformation(final Collection<String> values);
public abstract ETagHelper createETagHelper();
}

View File

@ -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;

View File

@ -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;

View File

@ -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 {
/**
* <p>Checks the preconditions of a read request with a given ETag value
* against the If-Match and If-None-Match HTTP headers.</p>
* <p>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.</p>
* <p>If the given ETag value is matched by the ETag information in the If-None-Match headers,
* <code>true</code> is returned, and applications are supposed to return an empty response
* with a "Not Modified" status code and the ETag header, <code>false</code> otherwise.</p>
* <p>All matching uses weak comparison as described in
* <a href="https://www.ietf.org/rfc/rfc7232.txt">RFC 7232</a>, section 2.3.2.</p>
* <p>This method does not nothing and returns <code>false</code> if the ETag value is
* <code>null</code>.</p>
* @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<String> ifMatchHeaders, Collection<String> ifNoneMatchHeaders)
throws PreconditionRequiredException;
/**
* <p>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.</p>
* <p>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.</p>
* <p>All matching uses weak comparison as described in
* <a href="https://www.ietf.org/rfc/rfc7232.txt">RFC 7232</a>, section 2.3.2.</p>
* <p>This method does not nothing if the ETag value is <code>null</code>.</p>
* @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<String> ifMatchHeaders, Collection<String> ifNoneMatchHeaders)
throws PreconditionRequiredException;
}

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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<String> values) {
final Collection<String> eTags = ETagParser.parse(values);
final boolean isAll = eTags.size() == 1 && eTags.iterator().next().equals("*");
return new ETagInformation(isAll,
isAll ? Collections.<String> emptySet() : Collections.unmodifiableCollection(eTags));
public ETagHelper createETagHelper() {
return new ETagHelperImpl();
}
}

View File

@ -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<String> ifMatchHeaders, final Collection<String> 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<String> ifMatchHeaders, final Collection<String> 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.,
* <code>If-Match</code> and <code>If-None-Match</code>.
* @param values the collection of header values
* @return an {@link ETagInformation} instance
*/
protected ETagInformation createETagInformation(final Collection<String> values) {
final Collection<String> eTags = ETagParser.parse(values);
final boolean isAll = eTags.size() == 1 && eTags.iterator().next().equals("*");
return new ETagInformation(isAll,
isAll ? Collections.<String> emptySet() : Collections.unmodifiableCollection(eTags));
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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.<String> 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.<String> 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\""));
}
}

View File

@ -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 {

View File

@ -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<UriResource> 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();

View File

@ -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 ?

View File

@ -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<String> ifMatchHeaders, final Collection<String> 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<String> ifMatchHeaders, final Collection<String> 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);
}
}
}
}

View File

@ -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;