mirror of
https://github.com/apache/olingo-odata4.git
synced 2025-03-06 08:39:14 +00:00
[OLINGO-663] clean-up
Change-Id: Id1359ca3243e42d83ce0bd3057da3477850730e6 Signed-off-by: Christian Amend <chrisam@apache.org>
This commit is contained in:
parent
a4913636dc
commit
c65ef5e9e7
@ -212,8 +212,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase {
|
||||
|
||||
// Check initial next link format
|
||||
URI nextLink = response.getBody().getNext();
|
||||
assertEquals("http://localhost:9080/odata-server-tecsvc/odata.svc/ESServerSidePaging?%24skiptoken=1", nextLink
|
||||
.toASCIIString());
|
||||
assertEquals(SERVICE_URI + "/ESServerSidePaging?%24skiptoken=1", nextLink.toASCIIString());
|
||||
|
||||
// Check subsequent next links
|
||||
response = client.getRetrieveRequestFactory()
|
||||
@ -221,8 +220,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase {
|
||||
.execute();
|
||||
|
||||
nextLink = response.getBody().getNext();
|
||||
assertEquals("http://localhost:9080/odata-server-tecsvc/odata.svc/ESServerSidePaging?%24skiptoken=2", nextLink
|
||||
.toASCIIString());
|
||||
assertEquals(SERVICE_URI + "/ESServerSidePaging?%24skiptoken=2", nextLink.toASCIIString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -239,7 +237,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase {
|
||||
|
||||
// Check initial next link format
|
||||
URI nextLink = response.getBody().getNext();
|
||||
assertEquals("http://localhost:9080/odata-server-tecsvc/odata.svc/ESServerSidePaging?%24count=true&%24skiptoken=1",
|
||||
assertEquals(SERVICE_URI + "/ESServerSidePaging?%24count=true&%24skiptoken=1",
|
||||
nextLink.toASCIIString());
|
||||
|
||||
int token = 1;
|
||||
@ -253,10 +251,8 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase {
|
||||
|
||||
nextLink = response.getBody().getNext();
|
||||
if (nextLink != null) {
|
||||
assertEquals(
|
||||
"http://localhost:9080/odata-server-tecsvc/odata.svc/ESServerSidePaging?%24count=true&%24skiptoken="
|
||||
+ token,
|
||||
nextLink.toASCIIString());
|
||||
assertEquals(SERVICE_URI + "/ESServerSidePaging?%24count=true&%24skiptoken=" + token,
|
||||
nextLink.toASCIIString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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.client.api.communication.response;
|
||||
|
||||
/**
|
||||
* This interface defines the response to an OData link operation request.
|
||||
*
|
||||
* @see org.apache.olingo.client.api.communication.request.cud.v3.ODataLinkCreateRequest
|
||||
* @see org.apache.olingo.client.api.communication.request.cud.v3.ODataLinkUpdateRequest
|
||||
*/
|
||||
public interface ODataLinkOperationResponse extends ODataResponse {
|
||||
//No additional methods needed for now.
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Information about the values of an ETag-relevant HTTP header.
|
||||
*/
|
||||
public class ETagInformation {
|
||||
private final boolean all;
|
||||
private final Collection<String> eTags;
|
||||
|
||||
public ETagInformation(final boolean all, final Collection<String> eTags) {
|
||||
this.all = all;
|
||||
this.eTags = eTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the information whether the values contain "*".
|
||||
*/
|
||||
public boolean isAll() {
|
||||
return all;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the collection of ETag values found.
|
||||
* It is empty if {@link #isAll()} returns <code>true</code>.
|
||||
*/
|
||||
public Collection<String> getETags() {
|
||||
return eTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Checks whether a given ETag value is matched by this ETag information,
|
||||
* using weak comparison as described in
|
||||
* <a href="https://www.ietf.org/rfc/rfc7232.txt">RFC 7232</a>, section 2.3.2.</p>
|
||||
* <p>If the given value is <code>null</code>, or if this ETag information
|
||||
* does not contain anything, the result is <code>false</code>.</p>
|
||||
* @param eTag the ETag value to match
|
||||
* @return a boolean match result
|
||||
*/
|
||||
public boolean isMatchedBy(final String eTag) {
|
||||
if (eTag == null) {
|
||||
return false;
|
||||
} else if (all) {
|
||||
return true;
|
||||
} else {
|
||||
for (final String candidate : eTags) {
|
||||
if ((eTag.startsWith("W/") ? eTag.substring(2) : eTag)
|
||||
.equals(candidate.startsWith("W/") ? candidate.substring(2) : candidate)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -23,13 +23,13 @@ import java.util.Collection;
|
||||
/**
|
||||
* Information about the values of an ETag-relevant HTTP header.
|
||||
*/
|
||||
public class EtagInformation {
|
||||
public class ETagInformation {
|
||||
private final boolean all;
|
||||
private final Collection<String> etags;
|
||||
private final Collection<String> eTags;
|
||||
|
||||
public EtagInformation(final boolean all, final Collection<String> etags) {
|
||||
public ETagInformation(final boolean all, final Collection<String> eTags) {
|
||||
this.all = all;
|
||||
this.etags = etags;
|
||||
this.eTags = eTags;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -43,8 +43,8 @@ public class EtagInformation {
|
||||
* Gets the collection of ETag values found.
|
||||
* It is empty if {@link #isAll()} returns <code>true</code>.
|
||||
*/
|
||||
public Collection<String> getEtags() {
|
||||
return etags;
|
||||
public Collection<String> getETags() {
|
||||
return eTags;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,17 +53,17 @@ public class EtagInformation {
|
||||
* <a href="https://www.ietf.org/rfc/rfc7232.txt">RFC 7232</a>, section 2.3.2.</p>
|
||||
* <p>If the given value is <code>null</code>, or if this ETag information
|
||||
* does not contain anything, the result is <code>false</code>.</p>
|
||||
* @param etag the ETag value to match
|
||||
* @param eTag the ETag value to match
|
||||
* @return a boolean match result
|
||||
*/
|
||||
public boolean isMatchedBy(final String etag) {
|
||||
if (etag == null) {
|
||||
public boolean isMatchedBy(final String eTag) {
|
||||
if (eTag == null) {
|
||||
return false;
|
||||
} else if (all) {
|
||||
return true;
|
||||
} else {
|
||||
for (final String candidate : etags) {
|
||||
if ((etag.startsWith("W/") ? etag.substring(2) : etag)
|
||||
for (final String candidate : eTags) {
|
||||
if ((eTag.startsWith("W/") ? eTag.substring(2) : eTag)
|
||||
.equals(candidate.startsWith("W/") ? candidate.substring(2) : candidate)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -118,11 +118,11 @@ public abstract class OData {
|
||||
public abstract EdmPrimitiveType createPrimitiveTypeInstance(EdmPrimitiveTypeKind kind);
|
||||
|
||||
/**
|
||||
* Creates Etag information from the values of a HTTP header
|
||||
* 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
|
||||
* @return an {@link ETagInformation} instance
|
||||
*/
|
||||
public abstract EtagInformation createEtagInformation(final Collection<String> values);
|
||||
public abstract ETagInformation createETagInformation(final Collection<String> values);
|
||||
}
|
||||
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* <p>Parses the values of HTTP header fields that contain a list of entity tags or a
|
||||
* single star character, i.e., <code>If-Match</code> and <code>If-None-Match</code>.</p>
|
||||
* <p>See <a href="https://www.ietf.org/rfc/rfc7232.txt">RFC 7232</a> for details;
|
||||
* there the following grammar is defined:</p>
|
||||
* <pre>
|
||||
* If-Match = "*" / 1#entity-tag
|
||||
* If-None-Match = "*" / 1#entity-tag
|
||||
* entity-tag = [ weak ] opaque-tag
|
||||
* weak = %x57.2F ; "W/", case-sensitive
|
||||
* opaque-tag = DQUOTE *etagc DQUOTE
|
||||
* etagc = %x21 / %x23-7E / %x80-FF
|
||||
* </pre>
|
||||
* <p>Values with illegal syntax do not contribute to the result but no exception is thrown.</p>
|
||||
*/
|
||||
public class ETagParser {
|
||||
|
||||
private static final Pattern ETAG = Pattern.compile("\\s*(,\\s*)+|((?:W/)?\"[!#-~\\x80-\\xFF]*\")");
|
||||
|
||||
protected static Collection<String> parse(final Collection<String> values) {
|
||||
if (values == null) {
|
||||
return Collections.<String> emptySet();
|
||||
}
|
||||
|
||||
Set<String> result = new HashSet<String>();
|
||||
for (final String value : values) {
|
||||
final Collection<String> part = parse(value);
|
||||
if (part.size() == 1 && part.iterator().next().equals("*")) {
|
||||
return part;
|
||||
} else {
|
||||
result.addAll(part);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Collection<String> parse(final String value) {
|
||||
if (value.trim().equals("*")) {
|
||||
return Collections.singleton("*");
|
||||
} else {
|
||||
Set<String> result = new HashSet<String>();
|
||||
String separator = "";
|
||||
int start = 0;
|
||||
Matcher matcher = ETAG.matcher(value.trim());
|
||||
while (matcher.find() && matcher.start() == start) {
|
||||
start = matcher.end();
|
||||
if (matcher.group(1) != null) {
|
||||
separator = matcher.group(1);
|
||||
} else if (separator != null) {
|
||||
result.add(matcher.group(2));
|
||||
separator = null;
|
||||
} else {
|
||||
return Collections.<String> emptySet();
|
||||
}
|
||||
}
|
||||
return matcher.hitEnd() ? result : Collections.<String> emptySet();
|
||||
}
|
||||
}
|
||||
}
|
@ -40,7 +40,7 @@ import java.util.regex.Pattern;
|
||||
* </pre>
|
||||
* <p>Values with illegal syntax do not contribute to the result but no exception is thrown.</p>
|
||||
*/
|
||||
public class EtagParser {
|
||||
public class ETagParser {
|
||||
|
||||
private static final Pattern ETAG = Pattern.compile("\\s*(,\\s*)+|((?:W/)?\"[!#-~\\x80-\\xFF]*\")");
|
||||
|
||||
|
@ -96,7 +96,7 @@ public class ODataHandler {
|
||||
} catch (PreconditionRequiredException e) {
|
||||
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
|
||||
handleException(request, response, serverError);
|
||||
}catch (ODataHandlerException e) {
|
||||
} catch (ODataHandlerException e) {
|
||||
ODataServerError serverError = ODataExceptionHelper.createServerErrorObject(e, null);
|
||||
handleException(request, response, serverError);
|
||||
} catch (ODataApplicationException e) {
|
||||
@ -175,7 +175,7 @@ public class ODataHandler {
|
||||
public void register(final CustomContentTypeSupport customContentTypeSupport) {
|
||||
this.customContentTypeSupport = customContentTypeSupport;
|
||||
}
|
||||
|
||||
|
||||
public CustomContentTypeSupport getCustomContentTypeSupport() {
|
||||
return customContentTypeSupport;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ 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.ETagInformation;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataHttpHandler;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
@ -119,10 +119,10 @@ 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 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));
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,9 @@ public class PreconditionRequiredException extends ODataTranslatedException {
|
||||
private static final long serialVersionUID = -8112658467394158700L;
|
||||
|
||||
public static enum MessageKeys implements MessageKey {
|
||||
/** no parameter */
|
||||
MISSING_HEADER,
|
||||
/** no parameter */
|
||||
INVALID_URI;
|
||||
|
||||
@Override
|
||||
@ -39,8 +41,7 @@ public class PreconditionRequiredException extends ODataTranslatedException {
|
||||
}
|
||||
|
||||
public PreconditionRequiredException(final String developmentMessage, final Throwable cause,
|
||||
final MessageKey messageKey,
|
||||
final String... parameters) {
|
||||
final MessageKey messageKey, final String... parameters) {
|
||||
super(developmentMessage, cause, messageKey, parameters);
|
||||
}
|
||||
|
||||
|
@ -28,10 +28,10 @@ import org.apache.olingo.server.api.processor.BatchProcessor;
|
||||
import org.apache.olingo.server.core.ODataHandler;
|
||||
import org.apache.olingo.server.core.deserializer.batch.BatchParserCommon;
|
||||
|
||||
public class BatchFascadeImpl implements BatchFacade {
|
||||
public class BatchFacadeImpl implements BatchFacade {
|
||||
private final BatchPartHandler partHandler;
|
||||
|
||||
public BatchFascadeImpl(final ODataHandler oDataHandler, final ODataRequest request,
|
||||
public BatchFacadeImpl(final ODataHandler oDataHandler, final ODataRequest request,
|
||||
final BatchProcessor batchProcessor,
|
||||
final boolean isStrict) {
|
||||
partHandler = new BatchPartHandler(oDataHandler, batchProcessor, this);
|
@ -45,7 +45,7 @@ public class BatchHandler {
|
||||
throws DeserializerException, SerializerException {
|
||||
validateRequest(request);
|
||||
|
||||
final BatchFacade operation = new BatchFascadeImpl(oDataHandler, request, batchProcessor, isStrict);
|
||||
final BatchFacade operation = new BatchFacadeImpl(oDataHandler, request, batchProcessor, isStrict);
|
||||
batchProcessor.processBatch(operation, request, response);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.hasItems;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
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();
|
||||
|
||||
@Test
|
||||
public void empty() {
|
||||
final ETagInformation eTagInformation = odata.createETagInformation(null);
|
||||
assertFalse(eTagInformation.isAll());
|
||||
assertNotNull(eTagInformation.getETags());
|
||||
assertTrue(eTagInformation.getETags().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loneStar() {
|
||||
final ETagInformation eTagInformation = odata.createETagInformation(Collections.singleton("*"));
|
||||
assertTrue(eTagInformation.isAll());
|
||||
assertNotNull(eTagInformation.getETags());
|
||||
assertTrue(eTagInformation.getETags().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void starWins() {
|
||||
final ETagInformation eTagInformation = odata.createETagInformation(Arrays.asList("\"ETag\"", "*"));
|
||||
assertTrue(eTagInformation.isAll());
|
||||
assertNotNull(eTagInformation.getETags());
|
||||
assertTrue(eTagInformation.getETags().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void starAsEtagAndEmptyEtag() {
|
||||
final ETagInformation eTagInformation = odata.createETagInformation(
|
||||
Collections.singleton("\"*\", \"\""));
|
||||
assertFalse(eTagInformation.isAll());
|
||||
assertNotNull(eTagInformation.getETags());
|
||||
assertThat(eTagInformation.getETags().size(), equalTo(2));
|
||||
assertThat(eTagInformation.getETags(), hasItems("\"*\"", "\"\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void severalEtags() {
|
||||
final ETagInformation eTagInformation = odata.createETagInformation(
|
||||
Arrays.asList("\"ETag1\"", "\"ETag2\",, , ,W/\"ETag3\", ,"));
|
||||
assertFalse(eTagInformation.isAll());
|
||||
assertNotNull(eTagInformation.getETags());
|
||||
assertThat(eTagInformation.getETags().size(), equalTo(3));
|
||||
assertThat(eTagInformation.getETags(), hasItems("\"ETag1\"", "\"ETag2\"", "W/\"ETag3\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void duplicateEtagValues() {
|
||||
final ETagInformation eTagInformation = odata.createETagInformation(
|
||||
Arrays.asList("\"ETag1\"", "\"ETag2\", W/\"ETag1\", \"ETag1\""));
|
||||
assertFalse(eTagInformation.isAll());
|
||||
assertNotNull(eTagInformation.getETags());
|
||||
assertThat(eTagInformation.getETags().size(), equalTo(3));
|
||||
assertThat(eTagInformation.getETags(), hasItems("\"ETag1\"", "\"ETag2\"", "W/\"ETag1\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void specialCharacters() {
|
||||
final ETagInformation eTagInformation = odata.createETagInformation(
|
||||
Collections.singleton("\"!#$%&'()*+,-./:;<=>?@[]^_`{|}~¡\u00FF\", \"ETag2\""));
|
||||
assertFalse(eTagInformation.isAll());
|
||||
assertNotNull(eTagInformation.getETags());
|
||||
assertThat(eTagInformation.getETags().size(), equalTo(2));
|
||||
assertThat(eTagInformation.getETags(), hasItems(
|
||||
"\"!#$%&'()*+,-./:;<=>?@[]^_`{|}~¡\u00FF\"", "\"ETag2\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongFormat() {
|
||||
final ETagInformation eTagInformation = odata.createETagInformation(
|
||||
Arrays.asList("\"ETag1\", ETag2", "w/\"ETag3\"", "W//\"ETag4\"", "W/ETag5",
|
||||
"\"\"ETag6\"\"", " \"ETag7\"\"ETag7\" ", "\"ETag8\" \"ETag8\"",
|
||||
"\"ETag 9\"", "\"ETag10\""));
|
||||
assertFalse(eTagInformation.isAll());
|
||||
assertNotNull(eTagInformation.getETags());
|
||||
assertThat(eTagInformation.getETags().size(), equalTo(2));
|
||||
assertThat(eTagInformation.getETags(), hasItems("\"ETag1\"", "\"ETag10\""));
|
||||
}
|
||||
|
||||
@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\""))
|
||||
.isMatchedBy("\"ETag4\""));
|
||||
assertFalse(odata.createETagInformation(Arrays.asList("\"ETag1\",\"ETag2\"", "\"ETag3\",\"ETag4\""))
|
||||
.isMatchedBy("\"ETag5\""));
|
||||
}
|
||||
}
|
@ -28,104 +28,104 @@ 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.ETagInformation;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.junit.Test;
|
||||
|
||||
public class EtagParserTest {
|
||||
public class ETagParserTest {
|
||||
|
||||
private static final OData odata = OData.newInstance();
|
||||
|
||||
@Test
|
||||
public void empty() {
|
||||
final EtagInformation etagInformation = odata.createEtagInformation(null);
|
||||
assertFalse(etagInformation.isAll());
|
||||
assertNotNull(etagInformation.getEtags());
|
||||
assertTrue(etagInformation.getEtags().isEmpty());
|
||||
final ETagInformation eTagInformation = odata.createETagInformation(null);
|
||||
assertFalse(eTagInformation.isAll());
|
||||
assertNotNull(eTagInformation.getETags());
|
||||
assertTrue(eTagInformation.getETags().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loneStar() {
|
||||
final EtagInformation etagInformation = odata.createEtagInformation(Collections.singleton("*"));
|
||||
assertTrue(etagInformation.isAll());
|
||||
assertNotNull(etagInformation.getEtags());
|
||||
assertTrue(etagInformation.getEtags().isEmpty());
|
||||
final ETagInformation eTagInformation = odata.createETagInformation(Collections.singleton("*"));
|
||||
assertTrue(eTagInformation.isAll());
|
||||
assertNotNull(eTagInformation.getETags());
|
||||
assertTrue(eTagInformation.getETags().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void starWins() {
|
||||
final EtagInformation etagInformation = odata.createEtagInformation(Arrays.asList("\"ETag\"", "*"));
|
||||
assertTrue(etagInformation.isAll());
|
||||
assertNotNull(etagInformation.getEtags());
|
||||
assertTrue(etagInformation.getEtags().isEmpty());
|
||||
final ETagInformation eTagInformation = odata.createETagInformation(Arrays.asList("\"ETag\"", "*"));
|
||||
assertTrue(eTagInformation.isAll());
|
||||
assertNotNull(eTagInformation.getETags());
|
||||
assertTrue(eTagInformation.getETags().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void starAsEtagAndEmptyEtag() {
|
||||
final EtagInformation etagInformation = odata.createEtagInformation(
|
||||
final ETagInformation eTagInformation = odata.createETagInformation(
|
||||
Collections.singleton("\"*\", \"\""));
|
||||
assertFalse(etagInformation.isAll());
|
||||
assertNotNull(etagInformation.getEtags());
|
||||
assertThat(etagInformation.getEtags().size(), equalTo(2));
|
||||
assertThat(etagInformation.getEtags(), hasItems("\"*\"", "\"\""));
|
||||
assertFalse(eTagInformation.isAll());
|
||||
assertNotNull(eTagInformation.getETags());
|
||||
assertThat(eTagInformation.getETags().size(), equalTo(2));
|
||||
assertThat(eTagInformation.getETags(), hasItems("\"*\"", "\"\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void severalEtags() {
|
||||
final EtagInformation etagInformation = odata.createEtagInformation(
|
||||
final ETagInformation eTagInformation = odata.createETagInformation(
|
||||
Arrays.asList("\"ETag1\"", "\"ETag2\",, , ,W/\"ETag3\", ,"));
|
||||
assertFalse(etagInformation.isAll());
|
||||
assertNotNull(etagInformation.getEtags());
|
||||
assertThat(etagInformation.getEtags().size(), equalTo(3));
|
||||
assertThat(etagInformation.getEtags(), hasItems("\"ETag1\"", "\"ETag2\"", "W/\"ETag3\""));
|
||||
assertFalse(eTagInformation.isAll());
|
||||
assertNotNull(eTagInformation.getETags());
|
||||
assertThat(eTagInformation.getETags().size(), equalTo(3));
|
||||
assertThat(eTagInformation.getETags(), hasItems("\"ETag1\"", "\"ETag2\"", "W/\"ETag3\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void duplicateEtagValues() {
|
||||
final EtagInformation etagInformation = odata.createEtagInformation(
|
||||
final ETagInformation eTagInformation = odata.createETagInformation(
|
||||
Arrays.asList("\"ETag1\"", "\"ETag2\", W/\"ETag1\", \"ETag1\""));
|
||||
assertFalse(etagInformation.isAll());
|
||||
assertNotNull(etagInformation.getEtags());
|
||||
assertThat(etagInformation.getEtags().size(), equalTo(3));
|
||||
assertThat(etagInformation.getEtags(), hasItems("\"ETag1\"", "\"ETag2\"", "W/\"ETag1\""));
|
||||
assertFalse(eTagInformation.isAll());
|
||||
assertNotNull(eTagInformation.getETags());
|
||||
assertThat(eTagInformation.getETags().size(), equalTo(3));
|
||||
assertThat(eTagInformation.getETags(), hasItems("\"ETag1\"", "\"ETag2\"", "W/\"ETag1\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void specialCharacters() {
|
||||
final EtagInformation etagInformation = odata.createEtagInformation(
|
||||
final ETagInformation eTagInformation = odata.createETagInformation(
|
||||
Collections.singleton("\"!#$%&'()*+,-./:;<=>?@[]^_`{|}~¡\u00FF\", \"ETag2\""));
|
||||
assertFalse(etagInformation.isAll());
|
||||
assertNotNull(etagInformation.getEtags());
|
||||
assertThat(etagInformation.getEtags().size(), equalTo(2));
|
||||
assertThat(etagInformation.getEtags(), hasItems(
|
||||
assertFalse(eTagInformation.isAll());
|
||||
assertNotNull(eTagInformation.getETags());
|
||||
assertThat(eTagInformation.getETags().size(), equalTo(2));
|
||||
assertThat(eTagInformation.getETags(), hasItems(
|
||||
"\"!#$%&'()*+,-./:;<=>?@[]^_`{|}~¡\u00FF\"", "\"ETag2\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongFormat() {
|
||||
final EtagInformation etagInformation = odata.createEtagInformation(
|
||||
final ETagInformation eTagInformation = odata.createETagInformation(
|
||||
Arrays.asList("\"ETag1\", ETag2", "w/\"ETag3\"", "W//\"ETag4\"", "W/ETag5",
|
||||
"\"\"ETag6\"\"", " \"ETag7\"\"ETag7\" ", "\"ETag8\" \"ETag8\"",
|
||||
"\"ETag 9\"", "\"ETag10\""));
|
||||
assertFalse(etagInformation.isAll());
|
||||
assertNotNull(etagInformation.getEtags());
|
||||
assertThat(etagInformation.getEtags().size(), equalTo(2));
|
||||
assertThat(etagInformation.getEtags(), hasItems("\"ETag1\"", "\"ETag10\""));
|
||||
assertFalse(eTagInformation.isAll());
|
||||
assertNotNull(eTagInformation.getETags());
|
||||
assertThat(eTagInformation.getETags().size(), equalTo(2));
|
||||
assertThat(eTagInformation.getETags(), hasItems("\"ETag1\"", "\"ETag10\""));
|
||||
}
|
||||
|
||||
@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(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\""))
|
||||
.isMatchedBy("\"ETag4\""));
|
||||
assertFalse(odata.createEtagInformation(Arrays.asList("\"ETag1\",\"ETag2\"", "\"ETag3\",\"ETag4\""))
|
||||
assertFalse(odata.createETagInformation(Arrays.asList("\"ETag1\",\"ETag2\"", "\"ETag3\",\"ETag4\""))
|
||||
.isMatchedBy("\"ETag5\""));
|
||||
}
|
||||
}
|
||||
|
@ -578,8 +578,8 @@ public class DataProvider {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Entity getEntityByReference(final String entityId, final String rawServiceRoot)
|
||||
|
||||
protected Entity getEntityByReference(final String entityId, final String rawServiceRoot)
|
||||
throws DataProviderException {
|
||||
try {
|
||||
final UriResourceEntitySet uriResource = odata.createUriHelper().parseEntityId(edm, entityId, rawServiceRoot);
|
||||
@ -594,7 +594,7 @@ public class DataProvider {
|
||||
throw new DataProviderException("Invalid entity-id", HttpStatusCode.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class DataProviderException extends ODataApplicationException {
|
||||
private static final long serialVersionUID = 5098059649321796156L;
|
||||
|
||||
@ -603,7 +603,7 @@ public class DataProvider {
|
||||
}
|
||||
|
||||
public DataProviderException(final String message) {
|
||||
super(message, HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
|
||||
this(message, HttpStatusCode.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
public DataProviderException(final String message, final HttpStatusCode statusCode) {
|
||||
|
@ -27,7 +27,6 @@ import org.apache.olingo.commons.api.data.EntityCollection;
|
||||
import org.apache.olingo.commons.api.data.Link;
|
||||
import org.apache.olingo.commons.api.data.Linked;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.edm.Edm;
|
||||
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
|
||||
import org.apache.olingo.commons.api.edm.EdmComplexType;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
@ -35,35 +34,23 @@ import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.edm.EdmStructuredType;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.server.api.deserializer.DeserializerException;
|
||||
import org.apache.olingo.server.api.uri.UriHelper;
|
||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||
import org.apache.olingo.server.tecsvc.data.DataProvider.DataProviderException;
|
||||
|
||||
public class RequestValidator {
|
||||
private DataProvider provider;
|
||||
private boolean isInsert;
|
||||
private boolean isPatch;
|
||||
private UriHelper uriHelper;
|
||||
private Edm edm;
|
||||
private String rawServiceRoot;
|
||||
private final DataProvider provider;
|
||||
private final boolean isInsert;
|
||||
private final boolean isPatch;
|
||||
private final String rawServiceRoot;
|
||||
|
||||
public RequestValidator(final DataProvider provider, final UriHelper uriHelper,
|
||||
final Edm edm, final String rawServiceRoot) {
|
||||
this.provider = provider;
|
||||
isInsert = true;
|
||||
this.uriHelper = uriHelper;
|
||||
this.edm = edm;
|
||||
this.rawServiceRoot = rawServiceRoot;
|
||||
public RequestValidator(final DataProvider provider, final String rawServiceRoot) {
|
||||
this(provider, false, false, rawServiceRoot);
|
||||
}
|
||||
|
||||
public RequestValidator(final DataProvider provider, final boolean isUpdate, final boolean isPatch,
|
||||
final UriHelper uriHelper, final Edm edm, final String rawServiceRoot) {
|
||||
final String rawServiceRoot) {
|
||||
this.provider = provider;
|
||||
isInsert = !isUpdate;
|
||||
this.isInsert = !isUpdate;
|
||||
this.isPatch = isPatch;
|
||||
this.uriHelper = uriHelper;
|
||||
this.edm = edm;
|
||||
this.rawServiceRoot = rawServiceRoot;
|
||||
}
|
||||
|
||||
@ -89,15 +76,15 @@ public class RequestValidator {
|
||||
newPath.add(edmProperty.getName());
|
||||
final EdmBindingTarget target = edmBindingTarget.getRelatedBindingTarget(buildPath(newPath));
|
||||
|
||||
final ValidatioResult bindingResult = validateBinding(navigationBinding, edmProperty, target);
|
||||
final ValidatioResult linkResult = validateNavigationLink(navigationLink,
|
||||
final ValidationResult bindingResult = validateBinding(navigationBinding, edmProperty);
|
||||
final ValidationResult linkResult = validateNavigationLink(navigationLink,
|
||||
edmProperty,
|
||||
target);
|
||||
|
||||
if ((isInsert && !edmProperty.isNullable()
|
||||
&& (bindingResult != ValidatioResult.FOUND
|
||||
&& linkResult != ValidatioResult.FOUND))
|
||||
|| (!(isInsert && isPatch) && !edmProperty.isNullable() && linkResult == ValidatioResult.EMPTY)) {
|
||||
&& (bindingResult != ValidationResult.FOUND
|
||||
&& linkResult != ValidationResult.FOUND))
|
||||
|| (!(isInsert && isPatch) && !edmProperty.isNullable() && linkResult == ValidationResult.EMPTY)) {
|
||||
throw new DataProviderException("Navigation property " + navPropertyName + " must not be null",
|
||||
HttpStatusCode.BAD_REQUEST);
|
||||
}
|
||||
@ -119,35 +106,35 @@ public class RequestValidator {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private ValidatioResult validateBinding(final Link navigationBindung, final EdmNavigationProperty edmProperty,
|
||||
final EdmBindingTarget edmBindingTarget) throws DataProviderException {
|
||||
if (navigationBindung == null) {
|
||||
return ValidatioResult.NOT_FOUND;
|
||||
private ValidationResult validateBinding(final Link navigationBinding, final EdmNavigationProperty edmProperty)
|
||||
throws DataProviderException {
|
||||
if (navigationBinding == null) {
|
||||
return ValidationResult.NOT_FOUND;
|
||||
}
|
||||
|
||||
if (edmProperty.isCollection()) {
|
||||
if (navigationBindung.getBindingLinks().size() == 0) {
|
||||
return ValidatioResult.EMPTY;
|
||||
if (navigationBinding.getBindingLinks().size() == 0) {
|
||||
return ValidationResult.EMPTY;
|
||||
}
|
||||
|
||||
for (final String bindingLink : navigationBindung.getBindingLinks()) {
|
||||
validateLink(bindingLink, edmBindingTarget);
|
||||
for (final String bindingLink : navigationBinding.getBindingLinks()) {
|
||||
validateLink(bindingLink);
|
||||
}
|
||||
} else {
|
||||
if (navigationBindung.getBindingLink() == null) {
|
||||
return ValidatioResult.EMPTY;
|
||||
if (navigationBinding.getBindingLink() == null) {
|
||||
return ValidationResult.EMPTY;
|
||||
}
|
||||
|
||||
validateLink(navigationBindung.getBindingLink(), edmBindingTarget);
|
||||
validateLink(navigationBinding.getBindingLink());
|
||||
}
|
||||
|
||||
return ValidatioResult.FOUND;
|
||||
return ValidationResult.FOUND;
|
||||
}
|
||||
|
||||
private ValidatioResult validateNavigationLink(final Link navigationLink, final EdmNavigationProperty edmProperty,
|
||||
private ValidationResult validateNavigationLink(final Link navigationLink, final EdmNavigationProperty edmProperty,
|
||||
final EdmBindingTarget edmBindingTarget) throws DataProviderException {
|
||||
if (navigationLink == null) {
|
||||
return ValidatioResult.NOT_FOUND;
|
||||
return ValidationResult.NOT_FOUND;
|
||||
}
|
||||
|
||||
if (edmProperty.isCollection()) {
|
||||
@ -168,21 +155,11 @@ public class RequestValidator {
|
||||
}
|
||||
}
|
||||
|
||||
return ValidatioResult.FOUND;
|
||||
return ValidationResult.FOUND;
|
||||
}
|
||||
|
||||
private void validateLink(final String bindingLink, final EdmBindingTarget edmBindungTarget)
|
||||
throws DataProviderException {
|
||||
try {
|
||||
final UriResourceEntitySet uriInfo = uriHelper.parseEntityId(edm, bindingLink, rawServiceRoot);
|
||||
final Entity entity = provider.read(uriInfo.getEntitySet(), uriInfo.getKeyPredicates());
|
||||
|
||||
if (entity == null) {
|
||||
throw new DataProviderException("Entity not found", HttpStatusCode.NOT_FOUND);
|
||||
}
|
||||
} catch (DeserializerException e) {
|
||||
throw new DataProviderException("Invalid binding link", HttpStatusCode.BAD_REQUEST);
|
||||
}
|
||||
private void validateLink(final String bindingLink) throws DataProviderException {
|
||||
provider.getEntityByReference(bindingLink, rawServiceRoot);
|
||||
}
|
||||
|
||||
private void validateEntitySetProperties(final List<Property> properties, final EdmBindingTarget edmBindingTarget,
|
||||
@ -190,7 +167,7 @@ public class RequestValidator {
|
||||
validateProperties(properties, edmBindingTarget, edmType, edmType.getKeyPredicateNames(), path);
|
||||
}
|
||||
|
||||
private void validateProperties(final List<Property> properties, final EdmBindingTarget edmBingingTarget,
|
||||
private void validateProperties(final List<Property> properties, final EdmBindingTarget edmBindingTarget,
|
||||
final EdmStructuredType edmType, final List<String> keyPredicateNames, final List<String> path)
|
||||
throws DataProviderException {
|
||||
|
||||
@ -212,7 +189,7 @@ public class RequestValidator {
|
||||
}
|
||||
|
||||
// Validate property value
|
||||
validatePropertyValue(property, edmProperty, edmBingingTarget, path);
|
||||
validatePropertyValue(property, edmProperty, edmBindingTarget, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -259,7 +236,7 @@ public class RequestValidator {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static enum ValidatioResult {
|
||||
private static enum ValidationResult {
|
||||
FOUND,
|
||||
NOT_FOUND,
|
||||
EMPTY
|
||||
|
@ -159,10 +159,8 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||
final DeserializerResult deserializerResult =
|
||||
odata.createDeserializer(ODataFormat.fromContentType(requestFormat))
|
||||
.entity(request.getBody(), edmEntityType);
|
||||
new RequestValidator(dataProvider,
|
||||
odata.createUriHelper(),
|
||||
serviceMetadata.getEdm(),
|
||||
request.getRawBaseUri()).validate(edmEntitySet, deserializerResult.getEntity());
|
||||
new RequestValidator(dataProvider, request.getRawBaseUri())
|
||||
.validate(edmEntitySet, deserializerResult.getEntity());
|
||||
|
||||
entity = dataProvider.create(edmEntitySet);
|
||||
dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, deserializerResult.getEntity(), false,
|
||||
@ -213,8 +211,6 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
|
||||
new RequestValidator(dataProvider,
|
||||
true, // Update
|
||||
request.getMethod() == HttpMethod.PATCH,
|
||||
odata.createUriHelper(),
|
||||
serviceMetadata.getEdm(),
|
||||
request.getRawBaseUri()).validate(edmEntitySet, changedEntity);
|
||||
|
||||
dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, changedEntity,
|
||||
|
@ -32,7 +32,7 @@ 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.ETagInformation;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
@ -262,12 +262,12 @@ public abstract class TechnicalProcessor implements Processor {
|
||||
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()) {
|
||||
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)) {
|
||||
if (odata.createETagInformation(ifNoneMatchHeaders).isMatchedBy(eTag)) {
|
||||
throw new ODataApplicationException("The entity has not been modified.",
|
||||
HttpStatusCode.NOT_MODIFIED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
@ -278,9 +278,9 @@ public abstract class TechnicalProcessor implements Processor {
|
||||
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()
|
||||
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);
|
||||
|
@ -27,7 +27,6 @@ import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.edm.EdmType;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.primitive.EdmNull;
|
||||
|
||||
public class TypedOperand extends VisitorOperand {
|
||||
|
||||
@ -56,7 +55,7 @@ public class TypedOperand extends VisitorOperand {
|
||||
|
||||
@Override
|
||||
public TypedOperand asTypedOperand(final EdmPrimitiveType... asTypes) throws ODataApplicationException {
|
||||
if (type.equals(EdmNull.getInstance())) {
|
||||
if (is(primNull)) {
|
||||
return this;
|
||||
} else if (isNull()) {
|
||||
return new TypedOperand(null, asTypes[0]);
|
||||
@ -103,7 +102,7 @@ public class TypedOperand extends VisitorOperand {
|
||||
if (type == oType && value != null && other.getValue() != null
|
||||
&& value.getClass() == other.getValue().getClass()) {
|
||||
return this;
|
||||
} else if (isNullLiteral() || other.isNullLiteral()) {
|
||||
} else if (is(primNull) || other.is(primNull)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -132,16 +131,12 @@ public class TypedOperand extends VisitorOperand {
|
||||
return clazz.cast(value);
|
||||
}
|
||||
|
||||
public boolean isNullLiteral() {
|
||||
return type.equals(EdmNull.getInstance());
|
||||
}
|
||||
|
||||
public boolean isNull() {
|
||||
return isNullLiteral() || value == null;
|
||||
return is(primNull) || value == null;
|
||||
}
|
||||
|
||||
public boolean isIntegerType() {
|
||||
return is(
|
||||
return is(primNull,
|
||||
primByte,
|
||||
primSByte,
|
||||
primInt16,
|
||||
@ -150,23 +145,18 @@ public class TypedOperand extends VisitorOperand {
|
||||
}
|
||||
|
||||
public boolean isDecimalType() {
|
||||
return is(
|
||||
return is(primNull,
|
||||
primSingle,
|
||||
primDouble,
|
||||
primDecimal);
|
||||
}
|
||||
|
||||
public boolean is(final EdmPrimitiveType... types) {
|
||||
if (isNullLiteral()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (EdmPrimitiveType type : types) {
|
||||
if (type.equals(this.type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,6 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||
import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.primitive.EdmNull;
|
||||
|
||||
public class UntypedOperand extends VisitorOperand {
|
||||
|
||||
@ -43,8 +42,8 @@ public class UntypedOperand extends VisitorOperand {
|
||||
Object newValue = null;
|
||||
|
||||
// First try the null literal
|
||||
if ((newValue = tryCast(literal, EdmNull.getInstance())) != null) {
|
||||
return new TypedOperand(newValue, EdmNull.getInstance());
|
||||
if ((newValue = tryCast(literal, primNull)) != null) {
|
||||
return new TypedOperand(newValue, primNull);
|
||||
}
|
||||
|
||||
// Than try the given types
|
||||
@ -65,8 +64,8 @@ public class UntypedOperand extends VisitorOperand {
|
||||
Object newValue = null;
|
||||
|
||||
// Null literal
|
||||
if ((newValue = tryCast(literal, EdmNull.getInstance())) != null) {
|
||||
return new TypedOperand(newValue, EdmNull.getInstance());
|
||||
if (primNull.validate(literal, null, null, null, null, null)) {
|
||||
return new TypedOperand(newValue, primNull);
|
||||
}
|
||||
|
||||
// String
|
||||
|
@ -29,11 +29,13 @@ import org.apache.olingo.commons.api.edm.EdmProperty;
|
||||
import org.apache.olingo.commons.api.edm.EdmType;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.primitive.EdmNull;
|
||||
|
||||
public abstract class VisitorOperand {
|
||||
final static private HashMap<EdmType, Class<?>> defaultTypeMapping = new HashMap<EdmType, Class<?>>();
|
||||
protected Object value;
|
||||
protected static final OData oData;
|
||||
protected static final EdmPrimitiveType primNull = EdmNull.getInstance();
|
||||
protected static final EdmPrimitiveType primString;
|
||||
protected static final EdmPrimitiveType primBoolean;
|
||||
protected static final EdmPrimitiveType primDateTimeOffset;
|
||||
|
@ -37,6 +37,7 @@ import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand.TypedOperand;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.operand.VisitorOperand;
|
||||
import org.apache.olingo.server.tecsvc.processor.queryoptions.expression.primitive.EdmNull;
|
||||
|
||||
public class MethodCallOperator {
|
||||
|
||||
@ -317,8 +318,10 @@ public class MethodCallOperator {
|
||||
throws ODataApplicationException {
|
||||
final TypedOperand operand = parameters.get(0).asTypedOperand();
|
||||
|
||||
if (operand.is(expectedTypes)) {
|
||||
if (!operand.isNull()) {
|
||||
if (operand.isNull()) {
|
||||
return new TypedOperand(null, EdmNull.getInstance());
|
||||
} else {
|
||||
if (operand.is(expectedTypes)) {
|
||||
Calendar calendar = null;
|
||||
if (operand.is(primDate)) {
|
||||
calendar = operand.getTypedValue(Calendar.class);
|
||||
@ -331,13 +334,10 @@ public class MethodCallOperator {
|
||||
} else {
|
||||
throw new ODataApplicationException("Invalid type", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
|
||||
return new TypedOperand(f.perform(calendar, operand), returnType);
|
||||
} else {
|
||||
return new TypedOperand(null, returnType);
|
||||
}
|
||||
} else {
|
||||
throw new ODataApplicationException("Invalid type", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -345,7 +345,7 @@ public class MethodCallOperator {
|
||||
throws ODataApplicationException {
|
||||
List<String> stringParameters = getParametersAsString();
|
||||
if (stringParameters.contains(null)) {
|
||||
return new TypedOperand(null, returnValue);
|
||||
return new TypedOperand(null, EdmNull.getInstance());
|
||||
} else {
|
||||
return new TypedOperand(f.perform(stringParameters), returnValue);
|
||||
}
|
||||
|
@ -31,15 +31,26 @@ public final class EdmNull implements EdmPrimitiveType {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return EDM_NAMESPACE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return getClass().getSimpleName().substring(3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EdmTypeKind getKind() {
|
||||
return EdmTypeKind.PRIMITIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getDefaultType() {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
protected String uriPrefix = "";
|
||||
|
||||
protected String uriSuffix = "";
|
||||
|
||||
@Override
|
||||
public FullQualifiedName getFullQualifiedName() {
|
||||
return new FullQualifiedName(getNamespace(), getName());
|
||||
@ -54,13 +65,8 @@ public final class EdmNull implements EdmPrimitiveType {
|
||||
public boolean validate(final String value,
|
||||
final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale,
|
||||
final Boolean isUnicode) {
|
||||
|
||||
try {
|
||||
valueOfString(value, isNullable, maxLength, precision, scale, isUnicode, getDefaultType());
|
||||
return true;
|
||||
} catch (final EdmPrimitiveTypeException e) {
|
||||
return false;
|
||||
}
|
||||
return value == null && (isNullable == null || isNullable)
|
||||
|| value.equals("null");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -68,14 +74,17 @@ public final class EdmNull implements EdmPrimitiveType {
|
||||
final Boolean isNullable, final Integer maxLength, final Integer precision,
|
||||
final Integer scale, final Boolean isUnicode, final Class<T> returnType)
|
||||
throws EdmPrimitiveTypeException {
|
||||
|
||||
if (value == null) {
|
||||
if (isNullable != null && !isNullable) {
|
||||
throw new EdmPrimitiveTypeException("The literal 'null' is not allowed.");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return internalValueOfString(value, isNullable, maxLength, precision, scale, isUnicode, returnType);
|
||||
if (value.equals("null")) {
|
||||
return null;
|
||||
} else {
|
||||
throw new EdmPrimitiveTypeException("The literal '" + value + "' has illegal content.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -88,28 +97,17 @@ public final class EdmNull implements EdmPrimitiveType {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return internalValueToString(value, isNullable, maxLength, precision, scale, isUnicode);
|
||||
return "null";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toUriLiteral(final String literal) {
|
||||
return literal == null ? null :
|
||||
uriPrefix.isEmpty() && uriSuffix.isEmpty() ? literal : uriPrefix + literal + uriSuffix;
|
||||
return literal == null ? null : literal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fromUriLiteral(final String literal) throws EdmPrimitiveTypeException {
|
||||
if (literal == null) {
|
||||
return null;
|
||||
} else if (uriPrefix.isEmpty() && uriSuffix.isEmpty()) {
|
||||
return literal;
|
||||
} else if (literal.length() >= uriPrefix.length() + uriSuffix.length()
|
||||
&& literal.startsWith(uriPrefix) && literal.endsWith(uriSuffix)) {
|
||||
|
||||
return literal.substring(uriPrefix.length(), literal.length() - uriSuffix.length());
|
||||
} else {
|
||||
throw new EdmPrimitiveTypeException("The literal '" + literal + "' has illegal content.");
|
||||
}
|
||||
return literal == null ? null : literal;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -117,26 +115,6 @@ public final class EdmNull implements EdmPrimitiveType {
|
||||
return new FullQualifiedName(getNamespace(), getName()).getFullQualifiedNameAsString();
|
||||
}
|
||||
|
||||
protected <T> T internalValueOfString(final String value, final Boolean isNullable, final Integer maxLength,
|
||||
final Integer precision,
|
||||
final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
|
||||
if (!value.equals("null")) {
|
||||
throw new EdmPrimitiveTypeException("The literal '" + value + "' has illegal content.");
|
||||
}
|
||||
|
||||
if (returnType.isAssignableFrom(Object.class)) {
|
||||
return returnType.cast(new Object());
|
||||
} else {
|
||||
throw new ClassCastException("unsupported return type " + returnType.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
protected <T> String internalValueToString(final T value, final Boolean isNullable, final Integer maxLength,
|
||||
final Integer precision,
|
||||
final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
|
||||
return "null";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
return this == obj || obj != null && getClass() == obj.getClass();
|
||||
@ -146,20 +124,4 @@ public final class EdmNull implements EdmPrimitiveType {
|
||||
public int hashCode() {
|
||||
return getClass().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return EDM_NAMESPACE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return getClass().getSimpleName().substring(3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EdmTypeKind getKind() {
|
||||
return EdmTypeKind.PRIMITIVE;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user