[OLINGO-695] Merge remote-tracking branch 'origin/master' into OLINGO-695_OSGi-Support

This commit is contained in:
Michael Bolz 2015-06-19 18:17:53 +02:00
commit 85cd9072e4
22 changed files with 270 additions and 277 deletions

View File

@ -80,7 +80,7 @@ public class ActionImportITCase extends AbstractBaseTestITCase {
request.setPrefer(getClient().newPreferences().returnMinimal());
final ODataInvokeResponse<ClientProperty> response = request.execute();
assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode());
assertEquals("return=\"minimal\"", response.getHeader(HeaderName.preferenceApplied).iterator().next());
assertEquals("return=minimal", response.getHeader(HeaderName.preferenceApplied).iterator().next());
}
@Test

View File

@ -415,7 +415,7 @@ public class BasicITCase extends AbstractBaseTestITCase {
final ODataEntityCreateResponse<ClientEntity> response = request.execute();
assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode());
assertEquals("return=\"minimal\"", response.getHeader(HeaderName.preferenceApplied).iterator().next());
assertEquals("return=minimal", response.getHeader(HeaderName.preferenceApplied).iterator().next());
assertEquals(SERVICE_URI + "/ESTwoPrim(1)", response.getHeader(HttpHeader.LOCATION).iterator().next());
}
@ -696,7 +696,7 @@ public class BasicITCase extends AbstractBaseTestITCase {
final ODataEntityUpdateResponse<ClientEntity> response = request.execute();
assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
assertEquals("return=\"representation\"", response.getHeader(HeaderName.preferenceApplied).iterator().next());
assertEquals("return=representation", response.getHeader(HeaderName.preferenceApplied).iterator().next());
assertTrue(response.getBody().getProperty("PropertyString").hasNullValue());
assertEquals(34, response.getBody().getProperty("PropertyDecimal").getPrimitiveValue().toValue());
}
@ -843,7 +843,7 @@ public class BasicITCase extends AbstractBaseTestITCase {
request.setPrefer(getClient().newPreferences().returnMinimal());
final ODataEntityUpdateResponse<ClientEntity> response = request.execute();
assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode());
assertEquals("return=\"minimal\"", response.getHeader(HeaderName.preferenceApplied).iterator().next());
assertEquals("return=minimal", response.getHeader(HeaderName.preferenceApplied).iterator().next());
final String cookie = response.getHeader(HttpHeader.SET_COOKIE).iterator().next();
final ODataEntityRequest<ClientEntity> entityRequest = client.getRetrieveRequestFactory()

View File

@ -380,7 +380,7 @@ public class PrimitiveComplexITCase extends AbstractBaseTestITCase {
final ODataValueUpdateResponse response = request.execute();
assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode());
assertEquals("return=\"minimal\"", response.getHeader(HeaderName.preferenceApplied).iterator().next());
assertEquals("return=minimal", response.getHeader(HeaderName.preferenceApplied).iterator().next());
}
@Test

View File

@ -268,7 +268,7 @@ public class SystemQueryOptionITCase extends AbstractBaseTestITCase {
request.setPrefer(getClient().newPreferences().maxPageSize(7));
final ODataRetrieveResponse<ClientEntitySet> response = request.execute();
assertEquals("odata.maxpagesize=\"7\"", response.getHeader(HeaderName.preferenceApplied).iterator().next());
assertEquals("odata.maxpagesize=7", response.getHeader(HeaderName.preferenceApplied).iterator().next());
assertEquals(SERVICE_URI + '/' + ES_SERVER_SIDE_PAGING + "?%24skiptoken=1%2A" + 7,
response.getBody().getNext().toASCIIString());
}

View File

@ -18,6 +18,7 @@
*/
package org.apache.olingo.client.api.communication.header;
import org.apache.olingo.commons.api.ODataPreferenceNames;
/**
* Values of the Prefer header.
@ -67,7 +68,7 @@ public class ODataPreferences {
* @return preference.
*/
public String allowEntityReferences() {
return PreferenceNames.allowEntityReferences.toString();
return ODataPreferenceNames.ALLOW_ENTITY_REFERENCES.toString();
}
/**
@ -130,7 +131,7 @@ public class ODataPreferences {
* @return preference.
*/
public String callback(final String url) {
return PreferenceNames.callback.toString() + ";url=\"" + url + "\"";
return ODataPreferenceNames.CALLBACK.toString() + ";url=\"" + url + "\"";
}
/**
@ -151,7 +152,7 @@ public class ODataPreferences {
* @return preference.
*/
public String continueOnError() {
return PreferenceNames.continueOnError.toString();
return ODataPreferenceNames.CONTINUE_ON_ERROR.toString();
}
/**
@ -198,7 +199,7 @@ public class ODataPreferences {
* @return preference.
*/
public String includeAnnotations(final String value) {
return PreferenceNames.includeAnnotations.toString() + "=" + value;
return ODataPreferenceNames.INCLUDE_ANNOTATIONS.toString() + "=" + value;
}
/**
@ -231,7 +232,7 @@ public class ODataPreferences {
* @return preference.
*/
public String maxPageSize(final int size) {
return PreferenceNames.maxPageSize.toString() + "=" + size;
return ODataPreferenceNames.MAX_PAGE_SIZE.toString() + "=" + size;
}
/**
@ -256,7 +257,7 @@ public class ODataPreferences {
* @return preference.
*/
public String trackChanges() {
return PreferenceNames.trackChanges.toString();
return ODataPreferenceNames.TRACK_CHANGES.toString();
}
/**
@ -291,7 +292,7 @@ public class ODataPreferences {
* @return preference.
*/
public String respondAsync() {
return PreferenceNames.respondAsync.toString();
return ODataPreferenceNames.RESPOND_ASYNC.toString();
}
/**
@ -311,7 +312,7 @@ public class ODataPreferences {
* @return preference.
*/
public String wait(final int value) {
return PreferenceNames.wait.toString() + "=" + value;
return ODataPreferenceNames.WAIT.toString() + "=" + value;
}
/**
@ -341,7 +342,7 @@ public class ODataPreferences {
* @return preference.
*/
public String returnMinimal() {
return PreferenceNames.odataReturn.toString() + "=minimal";
return ODataPreferenceNames.RETURN.toString() + "=minimal";
}
/**
@ -371,23 +372,15 @@ public class ODataPreferences {
* @return preference.
*/
public String returnRepresentation() {
return PreferenceNames.odataReturn.toString() + "=representation";
return ODataPreferenceNames.RETURN.toString() + "=representation";
}
/** Preferences not in the OData 4.0 standard. */
private static enum PreferenceNames {
returnContent("return-content"),
returnNoContent("return-no-content"),
keyAsSegment("KeyAsSegment"),
allowEntityReferences("odata.allow-entityreferences"),
callback("odata.callback"),
continueOnError("odata.continue-on-error"),
includeAnnotations("odata.include-annotations"),
maxPageSize("odata.maxpagesize"),
trackChanges("odata.track-changes"),
respondAsync("respond-async"),
wait("wait"),
odataReturn("return");
keyAsSegment("KeyAsSegment");
private final String preferenceName;

View File

@ -0,0 +1,46 @@
/*
* 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.commons.api;
/**
* Names of preferences defined in the OData standard.
*/
public enum ODataPreferenceNames {
ALLOW_ENTITY_REFERENCES("odata.allow-entityreferences"),
CALLBACK("odata.callback"),
CONTINUE_ON_ERROR("odata.continue-on-error"),
INCLUDE_ANNOTATIONS("odata.include-annotations"),
MAX_PAGE_SIZE("odata.maxpagesize"),
TRACK_CHANGES("odata.track-changes"),
RETURN("return"),
RESPOND_ASYNC("respond-async"),
WAIT("wait");
private final String preferenceName;
private ODataPreferenceNames(final String preferenceName) {
this.preferenceName = preferenceName;
}
@Override
public String toString() {
return preferenceName;
}
}

View File

@ -19,6 +19,7 @@
package org.apache.olingo.server.api.prefer;
import java.net.URI;
import java.util.Collections;
import java.util.Map;
/**
@ -101,7 +102,9 @@ public interface Preferences {
* @return a map from parameter names to parameter values
*/
public Map<String, String> getParameters() {
return parameters;
return parameters == null ?
Collections.<String, String> emptyMap() :
Collections.unmodifiableMap(parameters);
}
}
}

View File

@ -23,6 +23,7 @@ import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import org.apache.olingo.commons.api.ODataPreferenceNames;
import org.apache.olingo.server.api.prefer.Preferences.Return;
/**
@ -46,8 +47,8 @@ public class PreferencesApplied {
return Collections.unmodifiableMap(applied);
}
@Override
public String toString() {
/** Returns a string representation that can be used as value of a Preference-Applied HTTP response header. */
public String toValueString() {
StringBuilder result = new StringBuilder();
for (final String name : applied.keySet()) {
if (result.length() > 0) {
@ -55,14 +56,28 @@ public class PreferencesApplied {
}
result.append(name);
if (applied.get(name) != null) {
result.append('=').append('"')
final boolean safe = ODataPreferenceNames.ALLOW_ENTITY_REFERENCES.toString().equals(name)
|| ODataPreferenceNames.CALLBACK.toString().equals(name)
|| ODataPreferenceNames.CONTINUE_ON_ERROR.toString().equals(name)
|| ODataPreferenceNames.MAX_PAGE_SIZE.toString().equals(name)
|| ODataPreferenceNames.TRACK_CHANGES.toString().equals(name)
|| ODataPreferenceNames.RETURN.toString().equals(name)
|| ODataPreferenceNames.RESPOND_ASYNC.toString().equals(name)
|| ODataPreferenceNames.WAIT.toString().equals(name);
result.append('=')
.append(safe ? "" : '"')
.append(applied.get(name).replaceAll("\\\\|\"", "\\\\$0"))
.append('"');
.append(safe ? "" : '"');
}
}
return result.toString();
}
@Override
public String toString() {
return toValueString();
}
/** Initializes the builder. */
public static Builder with() {
return new Builder();
@ -71,16 +86,6 @@ public class PreferencesApplied {
/** Builder of OData serializer options. */
public static final class Builder {
private static final String ALLOW_ENTITY_REFERENCES = "odata.allow-entityreferences";
private static final String CALLBACK = "odata.callback";
private static final String CONTINUE_ON_ERROR = "odata.continue-on-error";
// private static final String INCLUDE_ANNOTATIONS = "odata.include-annotations";
private static final String MAX_PAGE_SIZE = "odata.maxpagesize";
private static final String TRACK_CHANGES = "odata.track-changes";
private static final String RETURN = "return";
private static final String RESPOND_ASYNC = "respond-async";
private static final String WAIT = "wait";
private final PreferencesApplied preferencesApplied;
private Builder() {
@ -89,49 +94,49 @@ public class PreferencesApplied {
/** Sets <code>odata.allow-entityreferences</code>. */
public Builder allowEntityReferences() {
add(ALLOW_ENTITY_REFERENCES, null);
add(ODataPreferenceNames.ALLOW_ENTITY_REFERENCES.toString(), null);
return this;
}
/** Sets <code>odata.callback</code>. */
public Builder callback() {
add(CALLBACK, null);
add(ODataPreferenceNames.CALLBACK.toString(), null);
return this;
}
/** Sets <code>odata.continue-on-error</code>. */
public Builder continueOnError() {
add(CONTINUE_ON_ERROR, null);
add(ODataPreferenceNames.CONTINUE_ON_ERROR.toString(), null);
return this;
}
/** Sets the value of the applied preference <code>odata.maxpagesize</code>. */
public Builder maxPageSize(final Integer maxPageSize) {
add(MAX_PAGE_SIZE, Integer.toString(maxPageSize));
add(ODataPreferenceNames.MAX_PAGE_SIZE.toString(), Integer.toString(maxPageSize));
return this;
}
/** Sets <code>odata.track-changes</code>. */
public Builder trackChanges() {
add(TRACK_CHANGES, null);
add(ODataPreferenceNames.TRACK_CHANGES.toString(), null);
return this;
}
/** Sets the value of the applied preference <code>return</code>. */
public Builder returnRepresentation(final Return returnRepresentation) {
add(RETURN, returnRepresentation.name().toLowerCase(Locale.ROOT));
add(ODataPreferenceNames.RETURN.toString(), returnRepresentation.name().toLowerCase(Locale.ROOT));
return this;
}
/** Sets <code>odata.respond-async</code>. */
public Builder respondAsync() {
add(RESPOND_ASYNC, null);
add(ODataPreferenceNames.RESPOND_ASYNC.toString(), null);
return this;
}
/** Sets the value of the applied preference <code>wait</code>. */
public Builder waitPreference(final Integer wait) {
add(WAIT, Integer.toString(wait));
add(ODataPreferenceNames.WAIT.toString(), Integer.toString(wait));
return this;
}

View File

@ -27,41 +27,41 @@ public class PreferencesAppliedTest {
@Test
public void empty() {
assertEquals("", PreferencesApplied.with().build().toString());
assertEquals("", PreferencesApplied.with().build().toValueString());
}
@Test
public void all() {
assertEquals("odata.allow-entityreferences, odata.callback,"
+ " odata.continue-on-error, odata.include-annotations=\"*\", odata.maxpagesize=\"42\","
+ " odata.track-changes, return=\"representation\", respond-async, wait=\"12345\"",
+ " odata.continue-on-error, odata.include-annotations=\"*\", odata.maxpagesize=42,"
+ " odata.track-changes, return=representation, respond-async, wait=12345",
PreferencesApplied.with().allowEntityReferences().callback().continueOnError()
.preference("odata.include-annotations", "*").maxPageSize(42).trackChanges()
.returnRepresentation(Return.REPRESENTATION).respondAsync().waitPreference(12345)
.build().toString());
.build().toValueString());
}
@Test
public void caseSensitivity() {
assertEquals("odata.include-annotations=\"*\", odata.maxpagesize=\"255\"",
assertEquals("odata.include-annotations=\"*\", odata.maxpagesize=255",
PreferencesApplied.with()
.preference("OData.Include-Annotations", "*").maxPageSize(0xFF)
.build().toString());
.build().toValueString());
}
@Test
public void multipleValues() {
assertEquals("return=\"minimal\", wait=\"1\"",
assertEquals("return=minimal, wait=1",
PreferencesApplied.with()
.returnRepresentation(Return.MINIMAL).returnRepresentation(Return.REPRESENTATION)
.preference(null, null).preference(null, "nullValue")
.waitPreference(1).waitPreference(2).waitPreference(3)
.build().toString());
.build().toValueString());
}
@Test
public void quotedValue() {
assertEquals("strangepreference=\"x\\\\y,\\\"abc\\\"z\"",
PreferencesApplied.with().preference("strangePreference", "x\\y,\"abc\"z").build().toString());
PreferencesApplied.with().preference("strangePreference", "x\\y,\"abc\"z").build().toValueString());
}
}

View File

@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.Locale;
import java.util.Map;
import org.apache.olingo.commons.api.ODataPreferenceNames;
import org.apache.olingo.server.api.prefer.Preferences;
/**
@ -32,16 +33,6 @@ import org.apache.olingo.server.api.prefer.Preferences;
*/
public class PreferencesImpl implements Preferences {
private static final String ALLOW_ENTITY_REFERENCES = "odata.allow-entityreferences";
private static final String CALLBACK = "odata.callback";
private static final String CONTINUE_ON_ERROR = "odata.continue-on-error";
// private static final String INCLUDE_ANNOTATIONS = "odata.include-annotations";
private static final String MAX_PAGE_SIZE = "odata.maxpagesize";
private static final String TRACK_CHANGES = "odata.track-changes";
private static final String RETURN = "return";
private static final String RESPOND_ASYNC = "respond-async";
private static final String WAIT = "wait";
private static final String URL = "url"; // parameter name for odata.callback
private final Map<String, Preference> preferences;
@ -55,15 +46,15 @@ public class PreferencesImpl implements Preferences {
}
public boolean hasAllowEntityReferences() {
return preferences.containsKey(ALLOW_ENTITY_REFERENCES);
return preferences.containsKey(ODataPreferenceNames.ALLOW_ENTITY_REFERENCES.toString());
}
public URI getCallback() {
if (preferences.containsKey(CALLBACK)
&& preferences.get(CALLBACK).getParameters() != null
&& preferences.get(CALLBACK).getParameters().get(URL) != null) {
if (preferences.containsKey(ODataPreferenceNames.CALLBACK.toString())
&& preferences.get(ODataPreferenceNames.CALLBACK.toString()).getParameters() != null
&& preferences.get(ODataPreferenceNames.CALLBACK.toString()).getParameters().get(URL) != null) {
try {
return URI.create(preferences.get(CALLBACK).getParameters().get(URL));
return URI.create(preferences.get(ODataPreferenceNames.CALLBACK.toString()).getParameters().get(URL));
} catch (final IllegalArgumentException e) {
return null;
}
@ -72,20 +63,20 @@ public class PreferencesImpl implements Preferences {
}
public boolean hasContinueOnError() {
return preferences.containsKey(CONTINUE_ON_ERROR);
return preferences.containsKey(ODataPreferenceNames.CONTINUE_ON_ERROR.toString());
}
public Integer getMaxPageSize() {
return getNonNegativeIntegerPreference(MAX_PAGE_SIZE);
return getNonNegativeIntegerPreference(ODataPreferenceNames.MAX_PAGE_SIZE.toString());
}
public boolean hasTrackChanges() {
return preferences.containsKey(TRACK_CHANGES);
return preferences.containsKey(ODataPreferenceNames.TRACK_CHANGES.toString());
}
public Return getReturn() {
if (preferences.containsKey(RETURN)) {
final String value = preferences.get(RETURN).getValue();
if (preferences.containsKey(ODataPreferenceNames.RETURN.toString())) {
final String value = preferences.get(ODataPreferenceNames.RETURN.toString()).getValue();
if (Return.REPRESENTATION.toString().toLowerCase(Locale.ROOT).equals(value)) {
return Return.REPRESENTATION;
} else if (Return.MINIMAL.toString().toLowerCase(Locale.ROOT).equals(value)) {
@ -96,11 +87,11 @@ public class PreferencesImpl implements Preferences {
}
public boolean hasRespondAsync() {
return preferences.containsKey(RESPOND_ASYNC);
return preferences.containsKey(ODataPreferenceNames.RESPOND_ASYNC.toString());
}
public Integer getWait() {
return getNonNegativeIntegerPreference(WAIT);
return getNonNegativeIntegerPreference(ODataPreferenceNames.WAIT.toString());
}
private Integer getNonNegativeIntegerPreference(final String name) {

View File

@ -24,7 +24,12 @@ import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.server.api.uri.UriResourceAction;
import org.apache.olingo.server.api.uri.UriResourceKind;
public class UriResourceActionImpl extends UriResourceTypedImpl implements UriResourceAction {
/**
* Implementation of the {@link UriResourceAction} interface. This class does not extend
* {@link org.apache.olingo.server.core.uri.UriResourceTypedImpl UriResourceTypedImpl}
* since that would allow type filters and subsequent path segments.
*/
public class UriResourceActionImpl extends UriResourceImpl implements UriResourceAction {
protected EdmAction action;
protected EdmActionImport actionImport;
@ -71,8 +76,12 @@ public class UriResourceActionImpl extends UriResourceTypedImpl implements UriRe
}
@Override
public String toString() {
public String toString(final boolean includeFilters) {
return actionImport == null ? (action == null ? "" : action.getName()) : actionImport.getName();
}
@Override
public String toString() {
return toString(false);
}
}

View File

@ -20,7 +20,6 @@ package org.apache.olingo.server.core.uri;
import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.server.api.uri.UriResourceKind;
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
@ -45,16 +44,11 @@ public abstract class UriResourceTypedImpl extends UriResourceImpl implements Ur
public String toString(final boolean includeFilters) {
if (includeFilters) {
if (typeFilter != null) {
return toString() + "/" + getFQN(typeFilter).toString();
return toString() + "/" + typeFilter.getFullQualifiedName().toString();
} else {
return toString();
}
}
return toString();
}
private FullQualifiedName getFQN(final EdmType type) {
return new FullQualifiedName(type.getNamespace(), type.getName());
}
}

View File

@ -25,6 +25,7 @@ import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitEx
import org.apache.olingo.server.api.uri.queryoption.expression.ExpressionVisitor;
import org.apache.olingo.server.api.uri.queryoption.expression.Member;
import org.apache.olingo.server.core.uri.UriInfoImpl;
import org.apache.olingo.server.core.uri.UriResourceActionImpl;
import org.apache.olingo.server.core.uri.UriResourceImpl;
import org.apache.olingo.server.core.uri.UriResourceTypedImpl;
import org.apache.olingo.server.core.uri.UriResourceWithKeysImpl;
@ -69,6 +70,8 @@ public class MemberImpl extends ExpressionImpl implements Member {
return type;
}
return lastTyped.getType();
} else if (lastResourcePart instanceof UriResourceActionImpl) {
return ((UriResourceActionImpl) lastResourcePart).getType();
} else {
return null;
}
@ -81,6 +84,8 @@ public class MemberImpl extends ExpressionImpl implements Member {
if (lastResourcePart instanceof UriResourceTypedImpl) {
UriResourceTypedImpl lastTyped = (UriResourceTypedImpl) lastResourcePart;
return lastTyped.isCollection();
} else if (lastResourcePart instanceof UriResourceActionImpl) {
return ((UriResourceActionImpl) lastResourcePart).isCollection();
}
return false;
}

View File

@ -112,7 +112,7 @@ public class TechnicalActionProcessor extends TechnicalProcessor
}
if (returnPreference != null) {
response.setHeader(HttpHeader.PREFERENCE_APPLIED,
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
PreferencesApplied.with().returnRepresentation(returnPreference).build().toValueString());
}
}
@ -160,7 +160,7 @@ public class TechnicalActionProcessor extends TechnicalProcessor
}
if (returnPreference != null) {
response.setHeader(HttpHeader.PREFERENCE_APPLIED,
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
PreferencesApplied.with().returnRepresentation(returnPreference).build().toValueString());
}
if (entityResult.isCreated()) {
response.setHeader(HttpHeader.LOCATION,
@ -213,7 +213,7 @@ public class TechnicalActionProcessor extends TechnicalProcessor
}
if (returnPreference != null) {
response.setHeader(HttpHeader.PREFERENCE_APPLIED,
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
PreferencesApplied.with().returnRepresentation(returnPreference).build().toValueString());
}
}
@ -253,7 +253,7 @@ public class TechnicalActionProcessor extends TechnicalProcessor
}
if (returnPreference != null) {
response.setHeader(HttpHeader.PREFERENCE_APPLIED,
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
PreferencesApplied.with().returnRepresentation(returnPreference).build().toValueString());
}
}
}
@ -298,7 +298,7 @@ public class TechnicalActionProcessor extends TechnicalProcessor
}
if (returnPreference != null) {
response.setHeader(HttpHeader.PREFERENCE_APPLIED,
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
PreferencesApplied.with().returnRepresentation(returnPreference).build().toValueString());
}
}
@ -339,7 +339,7 @@ public class TechnicalActionProcessor extends TechnicalProcessor
}
if (returnPreference != null) {
response.setHeader(HttpHeader.PREFERENCE_APPLIED,
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
PreferencesApplied.with().returnRepresentation(returnPreference).build().toValueString());
}
}
}

View File

@ -80,7 +80,7 @@ public class TechnicalBatchProcessor extends TechnicalProcessor implements Batch
response.setStatusCode(HttpStatusCode.ACCEPTED.getStatusCode());
if (continueOnError) {
response.setHeader(HttpHeader.PREFERENCE_APPLIED,
PreferencesApplied.with().continueOnError().build().toString());
PreferencesApplied.with().continueOnError().build().toValueString());
}
}

View File

@ -176,7 +176,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
}
if (returnPreference != null) {
response.setHeader(HttpHeader.PREFERENCE_APPLIED,
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
PreferencesApplied.with().returnRepresentation(returnPreference).build().toValueString());
}
response.setHeader(HttpHeader.LOCATION,
request.getRawBaseUri() + '/' + odata.createUriHelper().buildCanonicalURL(edmEntitySet, entity));
@ -232,7 +232,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
}
if (returnPreference != null) {
response.setHeader(HttpHeader.PREFERENCE_APPLIED,
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
PreferencesApplied.with().returnRepresentation(returnPreference).build().toValueString());
}
if (entity.getETag() != null) {
response.setHeader(HttpHeader.ETAG, entity.getETag());
@ -266,7 +266,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
}
if (returnPreference != null) {
response.setHeader(HttpHeader.PREFERENCE_APPLIED,
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
PreferencesApplied.with().returnRepresentation(returnPreference).build().toValueString());
}
if (entity.getETag() != null) {
response.setHeader(HttpHeader.ETAG, entity.getETag());
@ -476,7 +476,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
if (pageSize != null) {
response.setHeader(HttpHeader.PREFERENCE_APPLIED,
PreferencesApplied.with().maxPageSize(serverPageSize).build().toString());
PreferencesApplied.with().maxPageSize(serverPageSize).build().toValueString());
}
}

View File

@ -325,7 +325,7 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
}
if (returnPreference != null) {
response.setHeader(HttpHeader.PREFERENCE_APPLIED,
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
PreferencesApplied.with().returnRepresentation(returnPreference).build().toValueString());
}
if (entity.getETag() != null) {
response.setHeader(HttpHeader.ETAG, entity.getETag());

View File

@ -29,12 +29,8 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.commons.io.IOUtils;
import org.apache.olingo.commons.api.ODataException;
@ -48,12 +44,13 @@ import org.apache.olingo.commons.api.http.HttpContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
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.batch.BatchFacade;
import org.apache.olingo.server.api.edmx.EdmxReference;
import org.apache.olingo.server.api.processor.ActionComplexCollectionProcessor;
import org.apache.olingo.server.api.processor.ActionComplexProcessor;
@ -247,8 +244,9 @@ public class ODataHandlerTest {
final String uri = "$batch";
final BatchProcessor processor = mock(BatchProcessor.class);
dispatch(HttpMethod.POST, uri, processor);
// TODO: Verify that batch processing has been called.
dispatch(HttpMethod.POST, uri, null, HttpHeader.CONTENT_TYPE, ContentType.MULTIPART_MIXED.toContentTypeString(),
processor);
verify(processor).processBatch(any(BatchFacade.class), any(ODataRequest.class), any(ODataResponse.class));
dispatchMethodNotAllowed(HttpMethod.GET, uri, processor);
dispatchMethodNotAllowed(HttpMethod.PATCH, uri, processor);
@ -650,7 +648,7 @@ public class ODataHandlerTest {
@Test
public void dispatchReference() throws Exception {
final String uri = "ESAllPrim(0)/NavPropertyETTwoPrimOne/$ref";
final String uriDeleteMany = "ESAllPrim(0)/NavPropertyETTwoPrimMany/$ref";
final String uriMany = "ESAllPrim(0)/NavPropertyETTwoPrimMany/$ref";
final ReferenceProcessor processor = mock(ReferenceProcessor.class);
dispatch(HttpMethod.GET, uri, processor);
@ -665,29 +663,25 @@ public class ODataHandlerTest {
verify(processor, times(2)).updateReference(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
any(ContentType.class));
dispatch(HttpMethod.POST, uri.replace("One", "Many"), processor);
dispatchMethodNotAllowed(HttpMethod.POST, uri, processor);
dispatch(HttpMethod.POST, uriMany, processor);
verify(processor).createReference(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
any(ContentType.class));
dispatch(HttpMethod.DELETE, uriDeleteMany, "$id=ESTwoPrim(1)", null, Arrays.asList(new Processor[] { processor }));
dispatch(HttpMethod.DELETE, uriMany, "$id=ESTwoPrim(1)", null, null, processor);
verify(processor).deleteReference(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));
dispatchMethodNotAllowed(HttpMethod.POST, uri, processor);
}
@Test
public void dispatchReferenceCollection() throws Exception {
final String uri = "ESAllPrim(0)/NavPropertyETTwoPrimMany/$ref";
final ReferenceCollectionProcessor processor = mock(ReferenceCollectionProcessor.class);
final ReferenceProcessor singleProcessor = mock(ReferenceProcessor.class);
dispatch(HttpMethod.GET, uri, processor);
verify(processor).readReferenceCollection(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
any(ContentType.class));
dispatch(HttpMethod.DELETE, uri, singleProcessor);
verify(singleProcessor).deleteReference(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));
dispatchMethodNotAllowed(HttpMethod.PATCH, uri, processor);
dispatchMethodNotAllowed(HttpMethod.PUT, uri, processor);
}
@ -696,7 +690,7 @@ public class ODataHandlerTest {
public void unsupportedRequestContentType() throws Exception {
EntityProcessor processor = mock(EntityProcessor.class);
ErrorProcessor errorProcessor = mock(ErrorProcessor.class);
dispatch(HttpMethod.POST, "ESAllPrim", "", HttpHeader.CONTENT_TYPE, "some/unsupported", errorProcessor);
dispatch(HttpMethod.POST, "ESAllPrim", null, HttpHeader.CONTENT_TYPE, "some/unsupported", errorProcessor);
verifyZeroInteractions(processor);
verify(errorProcessor).processError(any(ODataRequest.class), any(ODataResponse.class),
any(ODataServerError.class),
@ -705,19 +699,6 @@ public class ODataHandlerTest {
private ODataResponse dispatch(final HttpMethod method, final String path, final String query,
final String headerName, final String headerValue, final Processor processor) {
Map<String, List<String>> headers = null;
if (headerName != null) {
headers = Collections.singletonMap(headerName, Collections.singletonList(headerValue));
}
List<Processor> processors = null;
if (processor != null) {
processors = Collections.singletonList(processor);
}
return dispatch(method, path, query, headers, processors);
}
private ODataResponse dispatch(final HttpMethod method, final String path, final String query,
final Map<String, List<String>> headers, final List<Processor> processors) {
ODataRequest request = new ODataRequest();
request.setMethod(method);
request.setRawBaseUri(BASE_URI);
@ -727,14 +708,11 @@ public class ODataHandlerTest {
request.setRawODataPath(path);
request.setRawQueryPath(query);
if (headers != null) {
Set<Map.Entry<String, List<String>>> headerSet = headers.entrySet();
for (Map.Entry<String, List<String>> headerItem : headerSet) {
request.addHeader(headerItem.getKey(), headerItem.getValue());
}
if (headerName != null) {
request.addHeader(headerName, Collections.singletonList(headerValue));
}
if (request.getHeaders(HttpHeader.CONTENT_TYPE) == null) {
if (headerName != HttpHeader.CONTENT_TYPE) {
request.addHeader(HttpHeader.CONTENT_TYPE, Collections.singletonList(
ODataFormat.JSON.getContentType().toContentTypeString()));
}
@ -745,10 +723,8 @@ public class ODataHandlerTest {
ODataHandler handler = new ODataHandler(odata, metadata);
if (processors != null && !processors.isEmpty()) {
for (Processor p : processors) {
handler.register(p);
}
if (processor != null) {
handler.register(processor);
}
final ODataResponse response = handler.process(request);

View File

@ -20,245 +20,202 @@ package org.apache.olingo.server.core;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.List;
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.etag.CustomETagSupport;
import org.apache.olingo.server.api.etag.PreconditionException;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.UriResourceValue;
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;
import org.apache.olingo.server.core.uri.validator.UriValidator;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
public class PreconditionsValidatorTest {
private static final Edm edm = new EdmProviderImpl(new EdmTechProvider());
// -------------- POSITIVE TESTS --------------------------------------------------------------------------------
@Test
public void simpleEntity() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, "*", "*").validatePreconditions(false);
validate("ESAllPrim(1)", null, "*", "*");
}
@Test
public void simpleEntityValue() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESMedia(1)/$value", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, "*", "*").validatePreconditions(true);
validate("ESMedia(1)/$value", null, "*", "*");
}
@Test
public void EntityAndToOneNavigation() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/NavPropertyETTwoPrimOne", null, null, getEdm());
new PreconditionsValidator(new ETagSupport("ESTwoPrim"), uriInfo, "*", "*").validatePreconditions(false);
validate("ESAllPrim(1)/NavPropertyETTwoPrimOne", "ESTwoPrim", "*", "*");
}
@Test
public void EntityAndToManyNavigationWithKey() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/NavPropertyETTwoPrimMany(1)", null, null, getEdm());
new PreconditionsValidator(new ETagSupport("ESTwoPrim"), uriInfo, "*", "*").validatePreconditions(false);
validate("ESAllPrim(1)/NavPropertyETTwoPrimMany(1)", "ESTwoPrim", "*", "*");
}
@Test
public void EntityAndToOneNavigationValue() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESKeyNav(1)/NavPropertyETMediaOne/$value", null, null, getEdm());
new PreconditionsValidator(new ETagSupport("ESMedia"), uriInfo, "*", "*").validatePreconditions(true);
validate("ESKeyNav(1)/NavPropertyETMediaOne/$value", "ESMedia", "*", "*");
}
@Test
public void boundActionOnEsKeyNav() throws Exception {
UriInfo uriInfo =
new Parser().parseUri("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null, null, getEdm());
new PreconditionsValidator(new ETagSupport("ESKeyNav"), uriInfo, "*", "*").validatePreconditions(false);
validate("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", "ESKeyNav", "*", "*");
}
@Test
public void boundActionOnEsKeyNavWithNavigation() throws Exception {
UriInfo uriInfo =
new Parser().parseUri("ESKeyNav(1)/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null,
null, getEdm());
new PreconditionsValidator(new ETagSupport("ESKeyNav"), uriInfo, "*", "*").validatePreconditions(false);
validate("ESKeyNav(1)/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav",
"ESKeyNav", "*", "*");
}
@Test
public void singleton() throws Exception {
UriInfo uriInfo = new Parser().parseUri("SI", null, null, getEdm());
new PreconditionsValidator(new ETagSupport("SI"), uriInfo, "*", "*").validatePreconditions(false);
validate("SI", "SI", "*", "*");
}
@Test
public void singletonWithNavigation() throws Exception {
UriInfo uriInfo = new Parser().parseUri("SINav/NavPropertyETKeyNavOne", null, null, getEdm());
new PreconditionsValidator(new ETagSupport("ESKeyNav"), uriInfo, "*", "*").validatePreconditions(false);
validate("SINav/NavPropertyETKeyNavOne", "ESKeyNav", "*", "*");
}
@Test
public void singletonWithNavigationValue() throws Exception {
UriInfo uriInfo =
new Parser().parseUri("SINav/NavPropertyETKeyNavOne/NavPropertyETMediaOne/$value", null, null, getEdm());
new PreconditionsValidator(new ETagSupport("ESMedia"), uriInfo, "*", "*").validatePreconditions(false);
validate("SINav/NavPropertyETKeyNavOne/NavPropertyETMediaOne/$value", "ESMedia", "*", "*");
}
@Test
public void singletonWithAction() throws Exception {
UriInfo uriInfo = new Parser().parseUri("SINav/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null, null, getEdm());
new PreconditionsValidator(new ETagSupport("SINav"), uriInfo, "*", "*").validatePreconditions(false);
validate("SINav/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", "SINav", "*", "*");
}
@Test
public void singletonWithActionAndNavigation() throws Exception {
UriInfo uriInfo =
new Parser().parseUri("SINav/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null, null,
getEdm());
new PreconditionsValidator(new ETagSupport("ESKeyNav"), uriInfo, "*", "*").validatePreconditions(false);
validate("SINav/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", "ESKeyNav", "*", "*");
}
@Test
public void simpleEntityValueValidationNotActiveForMedia() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESMedia(1)/$value", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(true, false), uriInfo, null, null).validatePreconditions(true);
CustomETagSupport support = mock(CustomETagSupport.class);
when(support.hasETag(any(EdmBindingTarget.class))).thenReturn(true);
when(support.hasMediaETag(any(EdmBindingTarget.class))).thenReturn(false);
final UriInfo uriInfo = new Parser().parseUri("ESMedia(1)/$value", null, null, edm);
new PreconditionsValidator(support, uriInfo, null, null).validatePreconditions(true);
}
// -------------- IGNORE VALIDATION TESTS -----------------------------------------------------------------------
@Test
public void entitySetMustNotLeadToException() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESAllPrim", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(false);
validate("ESAllPrim", null, null, null);
}
@Test
public void propertyMustNotLeadToException() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/PropertyInt16", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(false);
validate("ESAllPrim(1)/PropertyInt16", null, null, null);
}
@Test
public void propertyValueMustNotLeadToException() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/PropertyInt16/$value", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(true);
validate("ESAllPrim(1)/PropertyInt16/$value", null, null, null);
}
@Test
public void navigationToManyMustNotLeadToException() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/NavPropertyETTwoPrimMany", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(false);
validate("ESAllPrim(1)/NavPropertyETTwoPrimMany", null, null, null);
}
@Test
public void navigationOnPropertyMustNotLeadToException() throws Exception {
UriInfo uriInfo = new Parser().parseUri("ESAllPrim(1)/NavPropertyETTwoPrimOne/PropertyInt16", null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(false);
validate("ESAllPrim(1)/NavPropertyETTwoPrimOne/PropertyInt16", null, null, null);
}
@Test
public void navigationToManyOnActionMustNotLeadToException() throws Exception {
UriInfo uriInfo =
new Parser().parseUri("ESTwoPrim(1)/NavPropertyETAllPrimMany/Namespace1_Alias.BAESAllPrimRTETAllPrim", null,
null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(false);
validate("ESTwoPrim(1)/NavPropertyETAllPrimMany/Namespace1_Alias.BAESAllPrimRTETAllPrim", null, null, null);
}
@Test
public void navigationWithoutBindingMustNotLeadToAnException() throws Exception {
UriInfo uriInfo =
new Parser()
.parseUri(
"ESTwoBaseTwoKeyNav(PropertyInt16=1,PropertyString='test')"
+ "/NavPropertyETBaseTwoKeyNavMany(PropertyInt16=1,PropertyString='test')",
null, null, getEdm());
new PreconditionsValidator(new ETagSupport(), uriInfo, null, null).validatePreconditions(false);
public void navigationWithoutBindingMustNotLeadToException() throws Exception {
validate("ESTwoBaseTwoKeyNav(PropertyInt16=1,PropertyString='test')"
+ "/NavPropertyETBaseTwoKeyNavMany(PropertyInt16=1,PropertyString='test')",
null, null, null);
}
// -------------- NEGATIVE TESTS --------------------------------------------------------------------------------
@Test
public void positiveTestsMustLeadToAnExceptionIfNoHeaderIsPresent() throws Exception {
runException("ESAllPrim(1)", null);
runException("ESMedia(1)/$value", null);
runException("ESAllPrim(1)/NavPropertyETTwoPrimOne", null);
runException("ESAllPrim(1)/NavPropertyETTwoPrimMany(1)", null);
runException("ESKeyNav(1)/NavPropertyETMediaOne/$value", null);
runException("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null);
runException("ESKeyNav(1)/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null);
runException("ESAllPrim(1)");
runException("ESMedia(1)/$value");
runException("ESAllPrim(1)/NavPropertyETTwoPrimOne");
runException("ESAllPrim(1)/NavPropertyETTwoPrimMany(1)");
runException("ESKeyNav(1)/NavPropertyETMediaOne/$value");
runException("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav");
runException("ESKeyNav(1)/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav");
runException("SI", null);
runException("SINav/NavPropertyETKeyNavOne", null);
runException("SINav/NavPropertyETKeyNavOne/NavPropertyETMediaOne/$value", null);
runException("SINav/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null);
runException("SINav/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", null);
runException("SI");
runException("SINav/NavPropertyETKeyNavOne");
runException("SINav/NavPropertyETKeyNavOne/NavPropertyETMediaOne/$value");
runException("SINav/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav");
runException("SINav/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav");
}
@Ignore
@Test
@Test(expected = UriParserSemanticException.class)
public void resourceSegmentAfterActionMustLeadToUriParserException() throws Exception {
// TODO: Check with URI Parser
UriInfo uriInfo =
new Parser().parseUri("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav/PropertyInt16", null, null,
getEdm());
new UriValidator().validate(uriInfo, HttpMethod.GET);
new PreconditionsValidator(new ETagSupport("ESKeyNav"), uriInfo, "*", "*").validatePreconditions(false);
validate("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav/PropertyInt16", "ESKeyNav", "*", "*");
}
@Test(expected = UriParserSemanticException.class)
public void valueMustBeLastSegment() throws Exception {
new Parser().parseUri("ESMedia(1)/$value/PropertyInt16", null, null, getEdm());
validate("ESMedia(1)/$value/PropertyInt16", null, null, null);
}
private void runException(String uri, String expectedEntitySet) throws UriParserException {
UriInfo uriInfo = new Parser().parseUri(uri, null, null, getEdm());
private void validate(final String uri, final String entitySetName, final String ifMatch, final String ifNoneMatch)
throws UriParserException, PreconditionException {
final UriInfo uriInfo = new Parser().parseUri(uri, null, null, edm);
final List<UriResource> parts = uriInfo.getUriResourceParts();
final boolean isMedia = parts.get(parts.size() - 1) instanceof UriResourceValue
&& parts.get(parts.size() - 2) instanceof UriResourceEntitySet;
CustomETagSupport support = mock(CustomETagSupport.class);
final Answer<Boolean> answer = new Answer<Boolean>() {
public Boolean answer(final InvocationOnMock invocation) throws Throwable {
if (entitySetName != null) {
assertEquals(entitySetName, ((EdmBindingTarget) invocation.getArguments()[0]).getName());
}
return true;
}};
when(support.hasETag(any(EdmBindingTarget.class))).thenAnswer(answer);
when(support.hasMediaETag(any(EdmBindingTarget.class))).thenAnswer(answer);
new PreconditionsValidator(support, uriInfo, ifMatch, ifNoneMatch).validatePreconditions(isMedia);
}
private void runException(final String uri) throws UriParserException {
try {
CustomETagSupport etagSupport =
expectedEntitySet == null ? new ETagSupport() : new ETagSupport(expectedEntitySet);
boolean isMedia = uri.endsWith("$value");
new PreconditionsValidator(etagSupport, uriInfo, null, null).validatePreconditions(isMedia);
validate(uri, null, null, null);
fail("Expected a PreconditionRequiredException but was not thrown");
} catch (PreconditionException e) {
} catch (final PreconditionException e) {
assertEquals(PreconditionException.MessageKeys.MISSING_HEADER, e.getMessageKey());
}
}
private Edm getEdm() {
return new EdmProviderImpl(new EdmTechProvider());
}
public class ETagSupport implements CustomETagSupport {
private boolean eTag = true;
private boolean mediaETag = true;
private String entitySetName;
public ETagSupport() {}
public ETagSupport(String entitySetName) {
this.entitySetName = entitySetName;
}
public ETagSupport(boolean eTag, boolean mediaETag) {
this.eTag = eTag;
this.mediaETag = mediaETag;
}
@Override
public boolean hasETag(EdmBindingTarget entitySetOrSingeton) {
if (this.entitySetName != null) {
assertEquals(this.entitySetName, entitySetOrSingeton.getName());
}
return eTag;
}
@Override
public boolean hasMediaETag(EdmBindingTarget entitySetOrSingelton) {
if (this.entitySetName != null) {
assertEquals(this.entitySetName, entitySetOrSingelton.getName());
}
return mediaETag;
}
}
}

View File

@ -38,6 +38,7 @@ import org.apache.olingo.server.core.uri.testutil.EdmTechTestProvider;
import org.apache.olingo.server.core.uri.testutil.FilterValidator;
import org.apache.olingo.server.core.uri.testutil.ResourceValidator;
import org.apache.olingo.server.core.uri.testutil.TestUriValidator;
import org.apache.olingo.server.core.uri.validator.UriValidationException;
import org.apache.olingo.server.tecsvc.provider.ComplexTypeProvider;
import org.apache.olingo.server.tecsvc.provider.ContainerProvider;
import org.apache.olingo.server.tecsvc.provider.EntityTypeProvider;
@ -5201,6 +5202,17 @@ public class TestFullResourcePath {
.isExSemantic(UriParserSemanticException.MessageKeys.ONLY_FOR_ENTITY_TYPES);
testUri.runEx("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/PropertyCompTwoPrim/$count")
.isExSemantic(UriParserSemanticException.MessageKeys.ONLY_FOR_COLLECTIONS);
// Actions must not be followed by anything.
testUri.runEx(ContainerProvider.AIRT_STRING + "/$value")
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_KIND_BEFORE_VALUE);
testUri.runEx(ContainerProvider.AIRTCT_TWO_PRIM_PARAM + "/PropertyInt16")
.isExSemantic(UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS);
testUri.runEx("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')/"
+ "olingo.odata.test1.BAETTwoKeyNavRTETTwoKeyNav/olingo.odata.test1.ETTwoKeyNav")
.isExSemantic(UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS);
testUri.runEx("ESTwoKeyNav/olingo.odata.test1.BAESTwoKeyNavRTESTwoKeyNav/$count")
.isExValidation(UriValidationException.MessageKeys.UNALLOWED_KIND_BEFORE_COUNT);
}
@Test

View File

@ -193,7 +193,7 @@ public class TestUriParserImpl {
.isType(EntityTypeProvider.nameETTwoKeyTwoPrim, false);
testUri.runEx(ContainerProvider.AIRT_STRING + "/invalidElement")
.isExSemantic(UriParserSemanticException.MessageKeys.RESOURCE_PART_MUST_BE_PRECEDED_BY_STRUCTURAL_TYPE);
.isExSemantic(UriParserSemanticException.MessageKeys.RESOURCE_PART_ONLY_FOR_TYPED_PARTS);
}
@Test

View File

@ -19,7 +19,9 @@
package org.apache.olingo.server.core.uri.queryoption.expression;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
@ -134,7 +136,7 @@ public class ExpressionTest {
MemberImpl expression = new MemberImpl();
EdmEntityType entityType = edm.getEntityType(EntityTypeProvider.nameETKeyNav);
// UriResourceImplTyped
// UriResourceImpl
EdmAction action = edm.getUnboundAction(ActionProvider.nameUARTString);
UriInfoResource uriInfo = new UriInfoImpl().setKind(UriInfoKind.resource).addResourcePart(
new UriResourceActionImpl().setAction(action)).asUriInfoResource();
@ -146,24 +148,24 @@ public class ExpressionTest {
assertEquals("<UARTString>", expression.accept(new FilterTreeToText()));
// UriResourceImplTyped check collection = false case
assertEquals(false, expression.isCollection());
assertFalse(expression.isCollection());
// UriResourceImplTyped check collection = true case
action = edm.getUnboundAction(ActionProvider.nameUARTCollStringTwoParam);
expression.setResourcePath(new UriInfoImpl().setKind(UriInfoKind.resource).addResourcePart(
new UriResourceActionImpl().setAction(action))
expression.setResourcePath(new UriInfoImpl().setKind(UriInfoKind.resource)
.addResourcePart(new UriResourceActionImpl().setAction(action))
.asUriInfoResource());
assertEquals(true, expression.isCollection());
assertTrue(expression.isCollection());
// UriResourceImplTyped with filter
action = edm.getUnboundAction(ActionProvider.nameUARTString);
EdmFunction function = edm.getUnboundFunction(FunctionProvider.nameUFCRTETKeyNav, null);
expression.setResourcePath(new UriInfoImpl().setKind(UriInfoKind.resource).addResourcePart(
new UriResourceActionImpl().setAction(action).setTypeFilter(entityType))
new UriResourceFunctionImpl().setFunction(function).setEntryTypeFilter(entityType))
.asUriInfoResource());
assertEquals(entityType, expression.getType());
// UriResourceImplKeyPred
EdmFunction function = edm.getUnboundFunction(FunctionProvider.nameUFCRTETKeyNav, null);
function = edm.getUnboundFunction(FunctionProvider.nameUFCRTETKeyNav, null);
expression.setResourcePath(new UriInfoImpl().setKind(UriInfoKind.resource).addResourcePart(
new UriResourceFunctionImpl().setFunction(function))
.asUriInfoResource());
@ -192,7 +194,7 @@ public class ExpressionTest {
assertEquals(null, expression.getType());
// no typed collection else case
assertEquals(false, expression.isCollection());
assertFalse(expression.isCollection());
}
@Test