[OLINGO-206] Merge branch 'olingo-206-val' into m2
This commit is contained in:
commit
7dae5ef331
|
@ -18,6 +18,11 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.olingo.server.api.uri;
|
package org.apache.olingo.server.api.uri;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOption;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object acting as general access to URI information extracted from the request URI. Depending on
|
* Object acting as general access to URI information extracted from the request URI. Depending on
|
||||||
* the URI info kind different interfaces are used to provide access to that information. </p>
|
* the URI info kind different interfaces are used to provide access to that information. </p>
|
||||||
|
@ -43,4 +48,6 @@ public interface UriInfo extends
|
||||||
|
|
||||||
public UriInfoResource asUriInfoResource();
|
public UriInfoResource asUriInfoResource();
|
||||||
|
|
||||||
|
public Collection<SystemQueryOption> getSystemQueryOptions();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,5 +114,5 @@ public interface UriInfoResource {
|
||||||
* @return List of resource parts.
|
* @return List of resource parts.
|
||||||
*/
|
*/
|
||||||
List<UriResource> getUriResourceParts();
|
List<UriResource> getUriResourceParts();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,12 @@
|
||||||
package org.apache.olingo.server.core.uri;
|
package org.apache.olingo.server.core.uri;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||||
import org.apache.olingo.server.api.uri.UriInfo;
|
import org.apache.olingo.server.api.uri.UriInfo;
|
||||||
import org.apache.olingo.server.api.uri.UriInfoAll;
|
import org.apache.olingo.server.api.uri.UriInfoAll;
|
||||||
|
@ -44,22 +47,12 @@ import org.apache.olingo.server.api.uri.queryoption.SearchOption;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.SkipOption;
|
import org.apache.olingo.server.api.uri.queryoption.SkipOption;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.SkipTokenOption;
|
import org.apache.olingo.server.api.uri.queryoption.SkipTokenOption;
|
||||||
|
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOption;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
|
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
|
||||||
import org.apache.olingo.server.api.uri.queryoption.TopOption;
|
import org.apache.olingo.server.api.uri.queryoption.TopOption;
|
||||||
import org.apache.olingo.server.core.uri.queryoption.CountOptionImpl;
|
|
||||||
import org.apache.olingo.server.core.uri.queryoption.CustomQueryOptionImpl;
|
import org.apache.olingo.server.core.uri.queryoption.CustomQueryOptionImpl;
|
||||||
import org.apache.olingo.server.core.uri.queryoption.ExpandOptionImpl;
|
|
||||||
import org.apache.olingo.server.core.uri.queryoption.FilterOptionImpl;
|
|
||||||
import org.apache.olingo.server.core.uri.queryoption.FormatOptionImpl;
|
|
||||||
import org.apache.olingo.server.core.uri.queryoption.IdOptionImpl;
|
|
||||||
import org.apache.olingo.server.core.uri.queryoption.OrderByOptionImpl;
|
|
||||||
import org.apache.olingo.server.core.uri.queryoption.QueryOptionImpl;
|
import org.apache.olingo.server.core.uri.queryoption.QueryOptionImpl;
|
||||||
import org.apache.olingo.server.core.uri.queryoption.SearchOptionImpl;
|
|
||||||
import org.apache.olingo.server.core.uri.queryoption.SelectOptionImpl;
|
|
||||||
import org.apache.olingo.server.core.uri.queryoption.SkipOptionImpl;
|
|
||||||
import org.apache.olingo.server.core.uri.queryoption.SkipTokenOptionImpl;
|
|
||||||
import org.apache.olingo.server.core.uri.queryoption.SystemQueryOptionImpl;
|
import org.apache.olingo.server.core.uri.queryoption.SystemQueryOptionImpl;
|
||||||
import org.apache.olingo.server.core.uri.queryoption.TopOptionImpl;
|
|
||||||
|
|
||||||
public class UriInfoImpl implements UriInfo {
|
public class UriInfoImpl implements UriInfo {
|
||||||
|
|
||||||
|
@ -68,19 +61,10 @@ public class UriInfoImpl implements UriInfo {
|
||||||
private List<String> entitySetNames = new ArrayList<String>(); // for $entity
|
private List<String> entitySetNames = new ArrayList<String>(); // for $entity
|
||||||
private EdmEntityType entityTypeCast; // for $entity
|
private EdmEntityType entityTypeCast; // for $entity
|
||||||
|
|
||||||
// Query options
|
|
||||||
private List<CustomQueryOptionImpl> customQueryOptions = new ArrayList<CustomQueryOptionImpl>();
|
private List<CustomQueryOptionImpl> customQueryOptions = new ArrayList<CustomQueryOptionImpl>();
|
||||||
private ExpandOptionImpl expandOption;
|
|
||||||
private FilterOptionImpl filterOption;
|
HashMap<SystemQueryOptionKind, SystemQueryOption> systemQueryOptions =
|
||||||
private FormatOptionImpl formatOption;
|
new HashMap<SystemQueryOptionKind, SystemQueryOption>();
|
||||||
private IdOption idOption;
|
|
||||||
private CountOptionImpl inlineCountOption;
|
|
||||||
private OrderByOptionImpl orderByOption;
|
|
||||||
private SearchOptionImpl searchOption;
|
|
||||||
private SelectOptionImpl selectOption;
|
|
||||||
private SkipOptionImpl skipOption;
|
|
||||||
private SkipTokenOptionImpl skipTokenOption;
|
|
||||||
private TopOptionImpl topOption;
|
|
||||||
|
|
||||||
private String fragment;
|
private String fragment;
|
||||||
|
|
||||||
|
@ -162,27 +146,27 @@ public class UriInfoImpl implements UriInfo {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExpandOption getExpandOption() {
|
public ExpandOption getExpandOption() {
|
||||||
return expandOption;
|
return (ExpandOption) systemQueryOptions.get(SystemQueryOptionKind.EXPAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FilterOption getFilterOption() {
|
public FilterOption getFilterOption() {
|
||||||
return filterOption;
|
return (FilterOption) systemQueryOptions.get(SystemQueryOptionKind.FILTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FormatOption getFormatOption() {
|
public FormatOption getFormatOption() {
|
||||||
return formatOption;
|
return (FormatOption) systemQueryOptions.get(SystemQueryOptionKind.FORMAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IdOption getIdOption() {
|
public IdOption getIdOption() {
|
||||||
return idOption;
|
return (IdOption) systemQueryOptions.get(SystemQueryOptionKind.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CountOption getCountOption() {
|
public CountOption getCountOption() {
|
||||||
return inlineCountOption;
|
return (CountOption) systemQueryOptions.get(SystemQueryOptionKind.COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -201,33 +185,33 @@ public class UriInfoImpl implements UriInfo {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OrderByOption getOrderByOption() {
|
public OrderByOption getOrderByOption() {
|
||||||
return orderByOption;
|
return (OrderByOption) systemQueryOptions.get(SystemQueryOptionKind.ORDERBY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SearchOption getSearchOption() {
|
public SearchOption getSearchOption() {
|
||||||
|
|
||||||
return searchOption;
|
return (SearchOption) systemQueryOptions.get(SystemQueryOptionKind.SEARCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SelectOption getSelectOption() {
|
public SelectOption getSelectOption() {
|
||||||
return selectOption;
|
return (SelectOption) systemQueryOptions.get(SystemQueryOptionKind.SELECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkipOption getSkipOption() {
|
public SkipOption getSkipOption() {
|
||||||
return skipOption;
|
return (SkipOption) systemQueryOptions.get(SystemQueryOptionKind.SKIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SkipTokenOption getSkipTokenOption() {
|
public SkipTokenOption getSkipTokenOption() {
|
||||||
return skipTokenOption;
|
return (SkipTokenOption) systemQueryOptions.get(SystemQueryOptionKind.SKIPTOKEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TopOption getTopOption() {
|
public TopOption getTopOption() {
|
||||||
return topOption;
|
return (TopOption) systemQueryOptions.get(SystemQueryOptionKind.TOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UriInfoImpl setQueryOptions(final List<QueryOptionImpl> list) {
|
public UriInfoImpl setQueryOptions(final List<QueryOptionImpl> list) {
|
||||||
|
@ -249,28 +233,33 @@ public class UriInfoImpl implements UriInfo {
|
||||||
public UriInfoImpl setSystemQueryOption(final SystemQueryOptionImpl systemOption) {
|
public UriInfoImpl setSystemQueryOption(final SystemQueryOptionImpl systemOption) {
|
||||||
|
|
||||||
if (systemOption.getKind() == SystemQueryOptionKind.EXPAND) {
|
if (systemOption.getKind() == SystemQueryOptionKind.EXPAND) {
|
||||||
expandOption = (ExpandOptionImpl) systemOption;
|
systemQueryOptions.put(SystemQueryOptionKind.EXPAND, systemOption);
|
||||||
} else if (systemOption.getKind() == SystemQueryOptionKind.FILTER) {
|
} else if (systemOption.getKind() == SystemQueryOptionKind.FILTER) {
|
||||||
filterOption = (FilterOptionImpl) systemOption;
|
systemQueryOptions.put(SystemQueryOptionKind.FILTER, systemOption);
|
||||||
} else if (systemOption.getKind() == SystemQueryOptionKind.FORMAT) {
|
} else if (systemOption.getKind() == SystemQueryOptionKind.FORMAT) {
|
||||||
formatOption = (FormatOptionImpl) systemOption;
|
systemQueryOptions.put(SystemQueryOptionKind.FORMAT, systemOption);
|
||||||
} else if (systemOption.getKind() == SystemQueryOptionKind.ID) {
|
} else if (systemOption.getKind() == SystemQueryOptionKind.ID) {
|
||||||
idOption = (IdOptionImpl) systemOption;
|
systemQueryOptions.put(SystemQueryOptionKind.ID, systemOption);
|
||||||
} else if (systemOption.getKind() == SystemQueryOptionKind.COUNT) {
|
} else if (systemOption.getKind() == SystemQueryOptionKind.COUNT) {
|
||||||
inlineCountOption = (CountOptionImpl) systemOption;
|
systemQueryOptions.put(SystemQueryOptionKind.COUNT, systemOption);
|
||||||
} else if (systemOption.getKind() == SystemQueryOptionKind.ORDERBY) {
|
} else if (systemOption.getKind() == SystemQueryOptionKind.ORDERBY) {
|
||||||
orderByOption = (OrderByOptionImpl) systemOption;
|
systemQueryOptions.put(SystemQueryOptionKind.ORDERBY, systemOption);
|
||||||
} else if (systemOption.getKind() == SystemQueryOptionKind.SEARCH) {
|
} else if (systemOption.getKind() == SystemQueryOptionKind.SEARCH) {
|
||||||
searchOption = (SearchOptionImpl) systemOption;
|
systemQueryOptions.put(SystemQueryOptionKind.SEARCH, systemOption);
|
||||||
} else if (systemOption.getKind() == SystemQueryOptionKind.SELECT) {
|
} else if (systemOption.getKind() == SystemQueryOptionKind.SELECT) {
|
||||||
selectOption = (SelectOptionImpl) systemOption;
|
systemQueryOptions.put(SystemQueryOptionKind.SELECT, systemOption);
|
||||||
} else if (systemOption.getKind() == SystemQueryOptionKind.SKIP) {
|
} else if (systemOption.getKind() == SystemQueryOptionKind.SKIP) {
|
||||||
skipOption = (SkipOptionImpl) systemOption;
|
systemQueryOptions.put(SystemQueryOptionKind.SKIP, systemOption);
|
||||||
} else if (systemOption.getKind() == SystemQueryOptionKind.SKIPTOKEN) {
|
} else if (systemOption.getKind() == SystemQueryOptionKind.SKIPTOKEN) {
|
||||||
skipTokenOption = (SkipTokenOptionImpl) systemOption;
|
systemQueryOptions.put(SystemQueryOptionKind.SKIPTOKEN, systemOption);
|
||||||
} else if (systemOption.getKind() == SystemQueryOptionKind.TOP) {
|
} else if (systemOption.getKind() == SystemQueryOptionKind.TOP) {
|
||||||
topOption = (TopOptionImpl) systemOption;
|
systemQueryOptions.put(SystemQueryOptionKind.TOP, systemOption);
|
||||||
|
} else if (systemOption.getKind() == SystemQueryOptionKind.LEVELS) {
|
||||||
|
systemQueryOptions.put(SystemQueryOptionKind.LEVELS, systemOption);
|
||||||
|
} else {
|
||||||
|
throw new ODataRuntimeException("Unsupported System Query Option: " + systemOption.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,6 +280,11 @@ public class UriInfoImpl implements UriInfo {
|
||||||
|
|
||||||
public void removeResourcePart(final int index) {
|
public void removeResourcePart(final int index) {
|
||||||
pathParts.remove(index);
|
pathParts.remove(index);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<SystemQueryOption> getSystemQueryOptions() {
|
||||||
|
return Collections.unmodifiableCollection(systemQueryOptions.values());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -47,8 +47,10 @@ public abstract class UriResourceWithKeysImpl extends UriResourceImpl implements
|
||||||
|
|
||||||
public List<UriParameter> getKeyPredicates() {
|
public List<UriParameter> getKeyPredicates() {
|
||||||
List<UriParameter> retList = new ArrayList<UriParameter>();
|
List<UriParameter> retList = new ArrayList<UriParameter>();
|
||||||
for (UriParameterImpl item : keyPredicates) {
|
if (keyPredicates != null) {
|
||||||
retList.add(item);
|
for (UriParameterImpl item : keyPredicates) {
|
||||||
|
retList.add(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return retList;
|
return retList;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,7 @@ public class Parser {
|
||||||
(BatchEOFContext) parseRule(uri.pathSegmentListDecoded.get(0), ParserEntryRules.Batch);
|
(BatchEOFContext) parseRule(uri.pathSegmentListDecoded.get(0), ParserEntryRules.Batch);
|
||||||
|
|
||||||
uriParseTreeVisitor.visitBatchEOF(ctxBatchEOF);
|
uriParseTreeVisitor.visitBatchEOF(ctxBatchEOF);
|
||||||
|
readQueryParameter = true;
|
||||||
} else if (firstSegment.startsWith("$metadata")) {
|
} else if (firstSegment.startsWith("$metadata")) {
|
||||||
MetadataEOFContext ctxMetadataEOF =
|
MetadataEOFContext ctxMetadataEOF =
|
||||||
(MetadataEOFContext) parseRule(uri.pathSegmentListDecoded.get(0), ParserEntryRules.Metadata);
|
(MetadataEOFContext) parseRule(uri.pathSegmentListDecoded.get(0), ParserEntryRules.Metadata);
|
||||||
|
@ -206,7 +207,7 @@ public class Parser {
|
||||||
|
|
||||||
context.contextUriInfo.setSystemQueryOption(filterOption);
|
context.contextUriInfo.setSystemQueryOption(filterOption);
|
||||||
} else if (option.name.equals("$search")) {
|
} else if (option.name.equals("$search")) {
|
||||||
// TODO $search is not supported yet
|
throw new RuntimeException("System query option '$search' not implemented!");
|
||||||
} else if (option.name.equals("$select")) {
|
} else if (option.name.equals("$select")) {
|
||||||
SelectEOFContext ctxSelectEOF =
|
SelectEOFContext ctxSelectEOF =
|
||||||
(SelectEOFContext) parseRule(option.value, ParserEntryRules.Select);
|
(SelectEOFContext) parseRule(option.value, ParserEntryRules.Select);
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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.uri.validator;
|
||||||
|
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||||
|
|
||||||
|
public class UriValidationException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -3179078078053564742L;
|
||||||
|
|
||||||
|
public UriValidationException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UriValidationException(EdmPrimitiveTypeException e) {
|
||||||
|
super(e);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,540 @@
|
||||||
|
/*
|
||||||
|
* 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.uri.validator;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.olingo.commons.api.ODataRuntimeException;
|
||||||
|
import org.apache.olingo.commons.api.edm.Edm;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmReturnType;
|
||||||
|
import org.apache.olingo.commons.api.edm.EdmType;
|
||||||
|
import org.apache.olingo.server.api.uri.UriInfo;
|
||||||
|
import org.apache.olingo.server.api.uri.UriParameter;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResource;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResourceAction;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResourceFunction;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResourceKind;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
||||||
|
import org.apache.olingo.server.api.uri.UriResourcePartTyped;
|
||||||
|
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOption;
|
||||||
|
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOptionKind;
|
||||||
|
|
||||||
|
public class UriValidator {
|
||||||
|
|
||||||
|
//@formatter:off (Eclipse formatter)
|
||||||
|
//CHECKSTYLE:OFF (Maven checkstyle)
|
||||||
|
private boolean[][] decisionMatrix =
|
||||||
|
{
|
||||||
|
/* 0-FILTER 1-FORMAT 2-EXPAND 3-ID 4-COUNT 5-ORDERBY 6-SEARCH 7-SELECT 8-SKIP 9-SKIPTOKEN 10-LEVELS 11-TOP */
|
||||||
|
/* all 0 */ { true , true , true , false, true , true , true , true , true , true , true , false },
|
||||||
|
/* batch 1 */ { false, false, false, false, false, false, false, false, false, false, false, false },
|
||||||
|
/* crossjoin 2 */ { true , true , true , false, true , true , true , true , true , true , true , true },
|
||||||
|
/* entityId 3 */ { false, true , true , true , false, false, false, true , false, false, true , false },
|
||||||
|
/* metadata 4 */ { false, true , false, false, false, false, false, false, false, false, false, false },
|
||||||
|
/* resource 5 */ { false, true , false, false, false, false, false, false, false, false, false, false },
|
||||||
|
/* service 6 */ { false, true , false, false, false, false, false, false, false, false, false, false },
|
||||||
|
/* entitySet 7 */ { true , true , true , false, true , true , true , true , true , true , true , true },
|
||||||
|
/* entitySetCount 8 */ { false, false, false, false, false, false, false, false, false, false, false, false },
|
||||||
|
/* entity 9 */ { false, true , true , false, false, false, false, true , false, false, true , false },
|
||||||
|
/* mediaStream 10 */ { false, true , false, false, false, false, false, false, false, false, false, false },
|
||||||
|
/* references 11 */ { true , true , false, false, false, true , true , false, true , true , false, true },
|
||||||
|
/* reference 12 */ { false, true , false, false, false, false, false, false, false, false, false, false },
|
||||||
|
/* propertyComplex 13 */ { false, true , true , false, false, false, false, true , false, false, true , false },
|
||||||
|
/* propertyComplexCollection 14 */ { true , true , true , false, true , true , false, false, true , true , true , true },
|
||||||
|
/* propertyComplexCollectionCount 15 */ { false, false, false, false, false, false, false, false, false, false, false, false },
|
||||||
|
/* propertyPrimitive 16 */ { false, true , false, false, false, false, false, false, false, false, false, false },
|
||||||
|
/* propertyPrimitiveCollection 17 */ { true , true , false, false, false, true , false, false, true , true , false, true },
|
||||||
|
/* propertyPrimitiveCollectionCount 18 */ { false, false, false, false, false, false, false, false, false, false, false, false },
|
||||||
|
/* propertyPrimitiveValue 19 */ { false, true , false, false, false, false, false, false, false, false, false, false },
|
||||||
|
};
|
||||||
|
|
||||||
|
private boolean[][] decisionMatrixForHttpMethod =
|
||||||
|
{
|
||||||
|
/* 0-FILTER 1-FORMAT 2-EXPAND 3-ID 4-COUNT 5-ORDERBY 6-SEARCH 7-SELECT 8-SKIP 9-SKIPTOKEN 10-LEVELS 11-TOP */
|
||||||
|
/* GET 0 */ { true , true , true , true, true , true , true , true , true , true , true , true },
|
||||||
|
/* POST 0 */ { true , false , true , false, false , true , false , true , false , false , true , false },
|
||||||
|
/* PUT 0 */ { false , false , false , false, false , false , false , false , false , false , false , false },
|
||||||
|
/* DELETE 0 */ { false , false , false , false, false , false, false , false, false , false , false, false },
|
||||||
|
/* PATCH 0 */ { false , false , false , false, false , false , false , false , false , false , false , false },
|
||||||
|
/* MERGE 0 */ { false , false , false , false, false , false , false , false , false , false , false , false },
|
||||||
|
};
|
||||||
|
|
||||||
|
//CHECKSTYLE:ON
|
||||||
|
//@formatter:on
|
||||||
|
|
||||||
|
private enum RowIndexForUriType {
|
||||||
|
all(0),
|
||||||
|
batch(1),
|
||||||
|
crossjoin(2),
|
||||||
|
entityId(3),
|
||||||
|
metadata(4),
|
||||||
|
resource(5),
|
||||||
|
service(6),
|
||||||
|
entitySet(7),
|
||||||
|
entitySetCount(8),
|
||||||
|
entity(9),
|
||||||
|
mediaStream(10),
|
||||||
|
references(11),
|
||||||
|
reference(12),
|
||||||
|
propertyComplex(13),
|
||||||
|
propertyComplexCollection(14),
|
||||||
|
propertyComplexCollectionCount(15),
|
||||||
|
propertyPrimitive(16),
|
||||||
|
propertyPrimitiveCollection(17),
|
||||||
|
propertyPrimitiveCollectionCount(18),
|
||||||
|
propertyPrimitiveValue(19);
|
||||||
|
|
||||||
|
private int idx;
|
||||||
|
|
||||||
|
RowIndexForUriType(int i) {
|
||||||
|
idx = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum ColumnIndex {
|
||||||
|
filter(0),
|
||||||
|
format(1),
|
||||||
|
expand(2),
|
||||||
|
id(3),
|
||||||
|
count(4),
|
||||||
|
orderby(5),
|
||||||
|
search(6),
|
||||||
|
select(7),
|
||||||
|
skip(8),
|
||||||
|
skiptoken(9),
|
||||||
|
levels(10),
|
||||||
|
top(11);
|
||||||
|
|
||||||
|
private int idx;
|
||||||
|
|
||||||
|
ColumnIndex(int i) {
|
||||||
|
idx = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum RowIndexForHttpMethod {
|
||||||
|
GET(0),
|
||||||
|
POST(1),
|
||||||
|
PUT(2),
|
||||||
|
DELETE(3),
|
||||||
|
MERGE(4),
|
||||||
|
PATCH(5);
|
||||||
|
|
||||||
|
private int idx;
|
||||||
|
|
||||||
|
RowIndexForHttpMethod(int i) {
|
||||||
|
idx = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validate(final UriInfo uriInfo, final Edm edm, String httpMethod) throws UriValidationException {
|
||||||
|
|
||||||
|
validateForHttpMethod(uriInfo, httpMethod);
|
||||||
|
validateQueryOptions(uriInfo, edm);
|
||||||
|
validateKeyPredicateTypes(uriInfo, edm);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ColumnIndex colIndex(SystemQueryOptionKind queryOptionKind) {
|
||||||
|
ColumnIndex idx;
|
||||||
|
switch (queryOptionKind) {
|
||||||
|
case FILTER:
|
||||||
|
idx = ColumnIndex.filter;
|
||||||
|
break;
|
||||||
|
case FORMAT:
|
||||||
|
idx = ColumnIndex.format;
|
||||||
|
break;
|
||||||
|
case EXPAND:
|
||||||
|
idx = ColumnIndex.expand;
|
||||||
|
break;
|
||||||
|
case ID:
|
||||||
|
idx = ColumnIndex.id;
|
||||||
|
break;
|
||||||
|
case COUNT:
|
||||||
|
idx = ColumnIndex.count;
|
||||||
|
break;
|
||||||
|
case ORDERBY:
|
||||||
|
idx = ColumnIndex.orderby;
|
||||||
|
break;
|
||||||
|
case SEARCH:
|
||||||
|
idx = ColumnIndex.search;
|
||||||
|
break;
|
||||||
|
case SELECT:
|
||||||
|
idx = ColumnIndex.select;
|
||||||
|
break;
|
||||||
|
case SKIP:
|
||||||
|
idx = ColumnIndex.skip;
|
||||||
|
break;
|
||||||
|
case SKIPTOKEN:
|
||||||
|
idx = ColumnIndex.skiptoken;
|
||||||
|
break;
|
||||||
|
case LEVELS:
|
||||||
|
idx = ColumnIndex.levels;
|
||||||
|
break;
|
||||||
|
case TOP:
|
||||||
|
idx = ColumnIndex.top;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ODataRuntimeException("Unsupported option: " + queryOptionKind);
|
||||||
|
}
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RowIndexForUriType rowIndexForUriType(final UriInfo uriInfo, Edm edm) throws UriValidationException {
|
||||||
|
RowIndexForUriType idx;
|
||||||
|
|
||||||
|
switch (uriInfo.getKind()) {
|
||||||
|
case all:
|
||||||
|
idx = RowIndexForUriType.all;
|
||||||
|
break;
|
||||||
|
case batch:
|
||||||
|
idx = RowIndexForUriType.batch;
|
||||||
|
break;
|
||||||
|
case crossjoin:
|
||||||
|
idx = RowIndexForUriType.crossjoin;
|
||||||
|
break;
|
||||||
|
case entityId:
|
||||||
|
idx = RowIndexForUriType.entityId;
|
||||||
|
break;
|
||||||
|
case metadata:
|
||||||
|
idx = RowIndexForUriType.metadata;
|
||||||
|
break;
|
||||||
|
case resource:
|
||||||
|
idx = rowIndexForResourceKind(uriInfo, edm);
|
||||||
|
break;
|
||||||
|
case service:
|
||||||
|
idx = RowIndexForUriType.service;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ODataRuntimeException("Unsupported uriInfo kind: " + uriInfo.getKind());
|
||||||
|
}
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RowIndexForUriType rowIndexForResourceKind(UriInfo uriInfo, Edm edm) throws UriValidationException {
|
||||||
|
RowIndexForUriType idx;
|
||||||
|
|
||||||
|
int lastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 1;
|
||||||
|
UriResource lastPathSegment = uriInfo.getUriResourceParts().get(lastPathSegmentIndex);
|
||||||
|
|
||||||
|
switch (lastPathSegment.getKind()) {
|
||||||
|
case count:
|
||||||
|
idx = rowIndexForCount(uriInfo, lastPathSegment);
|
||||||
|
break;
|
||||||
|
case action:
|
||||||
|
idx = rowIndexForAction(lastPathSegment);
|
||||||
|
break;
|
||||||
|
case complexProperty:
|
||||||
|
idx = rowIndexForComplexProperty(lastPathSegment);
|
||||||
|
break;
|
||||||
|
case entitySet:
|
||||||
|
idx = rowIndexForEntitySet(lastPathSegment);
|
||||||
|
break;
|
||||||
|
case function:
|
||||||
|
idx = rowIndexForFunction(lastPathSegment);
|
||||||
|
break;
|
||||||
|
case navigationProperty:
|
||||||
|
idx =
|
||||||
|
((UriResourceNavigation) lastPathSegment).isCollection() ? RowIndexForUriType.entitySet
|
||||||
|
: RowIndexForUriType.entity;
|
||||||
|
break;
|
||||||
|
case primitiveProperty:
|
||||||
|
idx = rowIndexForPrimitiveProperty(lastPathSegment);
|
||||||
|
break;
|
||||||
|
case ref:
|
||||||
|
idx = rowIndexForRef(uriInfo, lastPathSegment);
|
||||||
|
break;
|
||||||
|
case root:
|
||||||
|
idx = RowIndexForUriType.service;
|
||||||
|
break;
|
||||||
|
case singleton:
|
||||||
|
idx = RowIndexForUriType.entity;
|
||||||
|
break;
|
||||||
|
case value:
|
||||||
|
idx = rowIndexForValue(uriInfo);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ODataRuntimeException("Unsupported uriResource kind: " + lastPathSegment.getKind());
|
||||||
|
}
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RowIndexForUriType rowIndexForValue(UriInfo uriInfo) throws UriValidationException {
|
||||||
|
RowIndexForUriType idx;
|
||||||
|
int secondLastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 2;
|
||||||
|
UriResource secondLastPathSegment = uriInfo.getUriResourceParts().get(secondLastPathSegmentIndex);
|
||||||
|
switch (secondLastPathSegment.getKind()) {
|
||||||
|
case primitiveProperty:
|
||||||
|
idx = RowIndexForUriType.propertyPrimitiveValue;
|
||||||
|
break;
|
||||||
|
case entitySet:
|
||||||
|
idx = RowIndexForUriType.mediaStream;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new UriValidationException("Unexpected kind in path segment before $value: "
|
||||||
|
+ secondLastPathSegment.getKind());
|
||||||
|
|
||||||
|
}
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RowIndexForUriType rowIndexForRef(UriInfo uriInfo, UriResource lastPathSegment)
|
||||||
|
throws UriValidationException {
|
||||||
|
RowIndexForUriType idx;
|
||||||
|
int secondLastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 2;
|
||||||
|
UriResource secondLastPathSegment = uriInfo.getUriResourceParts().get(secondLastPathSegmentIndex);
|
||||||
|
|
||||||
|
if (secondLastPathSegment instanceof UriResourcePartTyped) {
|
||||||
|
idx =
|
||||||
|
((UriResourcePartTyped) secondLastPathSegment).isCollection() ? RowIndexForUriType.references
|
||||||
|
: RowIndexForUriType.reference;
|
||||||
|
} else {
|
||||||
|
throw new UriValidationException("secondLastPathSegment not a class of UriResourcePartTyped: "
|
||||||
|
+ lastPathSegment.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RowIndexForUriType rowIndexForPrimitiveProperty(UriResource lastPathSegment)
|
||||||
|
throws UriValidationException {
|
||||||
|
RowIndexForUriType idx;
|
||||||
|
if (lastPathSegment instanceof UriResourcePartTyped) {
|
||||||
|
idx =
|
||||||
|
((UriResourcePartTyped) lastPathSegment).isCollection() ? RowIndexForUriType.propertyPrimitiveCollection
|
||||||
|
: RowIndexForUriType.propertyPrimitive;
|
||||||
|
} else {
|
||||||
|
throw new UriValidationException("lastPathSegment not a class of UriResourcePartTyped: "
|
||||||
|
+ lastPathSegment.getClass());
|
||||||
|
}
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RowIndexForUriType rowIndexForFunction(UriResource lastPathSegment) throws UriValidationException {
|
||||||
|
RowIndexForUriType idx;
|
||||||
|
UriResourceFunction urf = (UriResourceFunction) lastPathSegment;
|
||||||
|
EdmReturnType rt = urf.getFunction().getReturnType();
|
||||||
|
switch (rt.getType().getKind()) {
|
||||||
|
case ENTITY:
|
||||||
|
if (((EdmEntityType) rt.getType()).hasStream()) {
|
||||||
|
idx = RowIndexForUriType.mediaStream;
|
||||||
|
} else {
|
||||||
|
idx = rt.isCollection() ? RowIndexForUriType.entitySet : RowIndexForUriType.entity;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PRIMITIVE:
|
||||||
|
idx = rt.isCollection() ? RowIndexForUriType.propertyPrimitiveCollection : RowIndexForUriType.propertyPrimitive;
|
||||||
|
break;
|
||||||
|
case COMPLEX:
|
||||||
|
idx = rt.isCollection() ? RowIndexForUriType.propertyComplexCollection : RowIndexForUriType.propertyComplex;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new UriValidationException("Unsupported function return type: " + rt.getType().getKind());
|
||||||
|
}
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RowIndexForUriType rowIndexForEntitySet(UriResource lastPathSegment) throws UriValidationException {
|
||||||
|
RowIndexForUriType idx;
|
||||||
|
if (lastPathSegment instanceof UriResourcePartTyped) {
|
||||||
|
idx =
|
||||||
|
((UriResourcePartTyped) lastPathSegment).isCollection() ? RowIndexForUriType.entitySet
|
||||||
|
: RowIndexForUriType.entity;
|
||||||
|
} else {
|
||||||
|
throw new UriValidationException("lastPathSegment not a class of UriResourcePartTyped: "
|
||||||
|
+ lastPathSegment.getClass());
|
||||||
|
}
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RowIndexForUriType rowIndexForComplexProperty(UriResource lastPathSegment) throws UriValidationException {
|
||||||
|
RowIndexForUriType idx;
|
||||||
|
if (lastPathSegment instanceof UriResourcePartTyped) {
|
||||||
|
idx =
|
||||||
|
((UriResourcePartTyped) lastPathSegment).isCollection() ? RowIndexForUriType.propertyComplexCollection
|
||||||
|
: RowIndexForUriType.propertyComplex;
|
||||||
|
} else {
|
||||||
|
throw new UriValidationException("lastPathSegment not a class of UriResourcePartTyped: "
|
||||||
|
+ lastPathSegment.getClass());
|
||||||
|
}
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RowIndexForUriType rowIndexForAction(UriResource lastPathSegment) throws UriValidationException {
|
||||||
|
RowIndexForUriType idx;
|
||||||
|
UriResourceAction ura = (UriResourceAction) lastPathSegment;
|
||||||
|
EdmReturnType rt = ura.getAction().getReturnType();
|
||||||
|
switch (rt.getType().getKind()) {
|
||||||
|
case ENTITY:
|
||||||
|
if (((EdmEntityType) rt.getType()).hasStream()) {
|
||||||
|
idx = RowIndexForUriType.mediaStream;
|
||||||
|
} else {
|
||||||
|
idx = rt.isCollection() ? RowIndexForUriType.entitySet : RowIndexForUriType.entity;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PRIMITIVE:
|
||||||
|
idx = rt.isCollection() ? RowIndexForUriType.propertyPrimitiveCollection : RowIndexForUriType.propertyPrimitive;
|
||||||
|
break;
|
||||||
|
case COMPLEX:
|
||||||
|
idx = rt.isCollection() ? RowIndexForUriType.propertyComplexCollection : RowIndexForUriType.propertyComplex;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new UriValidationException("Unsupported action return type: " + rt.getType().getKind());
|
||||||
|
}
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RowIndexForUriType rowIndexForCount(UriInfo uriInfo, UriResource lastPathSegment)
|
||||||
|
throws UriValidationException {
|
||||||
|
|
||||||
|
RowIndexForUriType idx;
|
||||||
|
int secondLastPathSegmentIndex = uriInfo.getUriResourceParts().size() - 2;
|
||||||
|
UriResource secondLastPathSegment = uriInfo.getUriResourceParts().get(secondLastPathSegmentIndex);
|
||||||
|
switch (secondLastPathSegment.getKind()) {
|
||||||
|
case entitySet:
|
||||||
|
idx = RowIndexForUriType.entitySetCount;
|
||||||
|
break;
|
||||||
|
case complexProperty:
|
||||||
|
idx = RowIndexForUriType.propertyComplexCollectionCount;
|
||||||
|
break;
|
||||||
|
case primitiveProperty:
|
||||||
|
idx = RowIndexForUriType.propertyPrimitiveCollectionCount;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new UriValidationException("Illegal path part kind: " + lastPathSegment.getKind());
|
||||||
|
}
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateQueryOptions(final UriInfo uriInfo, Edm edm) throws UriValidationException {
|
||||||
|
RowIndexForUriType row = rowIndexForUriType(uriInfo, edm);
|
||||||
|
|
||||||
|
for (SystemQueryOption option : uriInfo.getSystemQueryOptions()) {
|
||||||
|
ColumnIndex col = colIndex(option.getKind());
|
||||||
|
|
||||||
|
if (!decisionMatrix[row.getIndex()][col.getIndex()]) {
|
||||||
|
throw new UriValidationException("System query option not allowed: " + option.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateForHttpMethod(UriInfo uriInfo, String httpMethod) throws UriValidationException {
|
||||||
|
RowIndexForHttpMethod row = rowIndexForHttpMethod(httpMethod);
|
||||||
|
|
||||||
|
for (SystemQueryOption option : uriInfo.getSystemQueryOptions()) {
|
||||||
|
ColumnIndex col = colIndex(option.getKind());
|
||||||
|
if (!decisionMatrixForHttpMethod[row.getIndex()][col.getIndex()]) {
|
||||||
|
throw new UriValidationException("System query option " + option.getName() + " not allowed for method "
|
||||||
|
+ httpMethod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private RowIndexForHttpMethod rowIndexForHttpMethod(String httpMethod) throws UriValidationException {
|
||||||
|
RowIndexForHttpMethod idx;
|
||||||
|
|
||||||
|
if ("GET".equalsIgnoreCase(httpMethod)) {
|
||||||
|
idx = RowIndexForHttpMethod.GET;
|
||||||
|
} else if ("POST".equalsIgnoreCase(httpMethod)) {
|
||||||
|
idx = RowIndexForHttpMethod.POST;
|
||||||
|
} else if ("PUT".equalsIgnoreCase(httpMethod)) {
|
||||||
|
idx = RowIndexForHttpMethod.PUT;
|
||||||
|
} else if ("DELETE".equalsIgnoreCase(httpMethod)) {
|
||||||
|
idx = RowIndexForHttpMethod.DELETE;
|
||||||
|
} else if ("PATCH".equalsIgnoreCase(httpMethod)) {
|
||||||
|
idx = RowIndexForHttpMethod.PATCH;
|
||||||
|
} else if ("MERGE".equalsIgnoreCase(httpMethod)) {
|
||||||
|
idx = RowIndexForHttpMethod.MERGE;
|
||||||
|
} else {
|
||||||
|
throw new UriValidationException("HTTP method not supported: " + httpMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateKeyPredicateTypes(final UriInfo uriInfo, final Edm edm) throws UriValidationException {
|
||||||
|
try {
|
||||||
|
for (UriResource pathSegment : uriInfo.getUriResourceParts()) {
|
||||||
|
if (pathSegment.getKind() == UriResourceKind.entitySet) {
|
||||||
|
UriResourceEntitySet pathEntitySet = (UriResourceEntitySet) pathSegment;
|
||||||
|
|
||||||
|
EdmEntityType type = pathEntitySet.getEntityType();
|
||||||
|
List<EdmKeyPropertyRef> keys = type.getKeyPropertyRefs();
|
||||||
|
List<UriParameter> keyPredicates = pathEntitySet.getKeyPredicates();
|
||||||
|
|
||||||
|
if (null != keyPredicates) {
|
||||||
|
|
||||||
|
HashMap<String, EdmKeyPropertyRef> edmKeys = new HashMap<String, EdmKeyPropertyRef>();
|
||||||
|
for (EdmKeyPropertyRef key : keys) {
|
||||||
|
edmKeys.put(key.getKeyPropertyName(), key);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (UriParameter keyPredicate : keyPredicates) {
|
||||||
|
String name = keyPredicate.getName();
|
||||||
|
String value = keyPredicate.getText();
|
||||||
|
EdmKeyPropertyRef edmKey = edmKeys.get(name);
|
||||||
|
|
||||||
|
if (edmKey == null) {
|
||||||
|
throw new UriValidationException("Unknown key property: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
EdmType edmType = edmKey.getProperty().getType();
|
||||||
|
EdmPrimitiveType edmPrimitiveType = (EdmPrimitiveType) edmType;
|
||||||
|
|
||||||
|
String edmLiteral = edmPrimitiveType.fromUriLiteral(value);
|
||||||
|
edmPrimitiveType.validate(edmLiteral, edmKey.getProperty().isNullable(), edmKey.getProperty()
|
||||||
|
.getMaxLength(), edmKey.getProperty().getPrecision(), edmKey.getProperty().getScale(), edmKey
|
||||||
|
.getProperty().isUnicode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (EdmPrimitiveTypeException e) {
|
||||||
|
throw new UriValidationException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,330 @@
|
||||||
|
/*
|
||||||
|
* 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.uri.validator;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import org.apache.olingo.commons.api.edm.Edm;
|
||||||
|
import org.apache.olingo.server.api.uri.UriInfo;
|
||||||
|
import org.apache.olingo.server.core.edm.provider.EdmProviderImpl;
|
||||||
|
import org.apache.olingo.server.core.testutil.EdmTechProvider;
|
||||||
|
import org.apache.olingo.server.core.uri.parser.Parser;
|
||||||
|
import org.apache.olingo.server.core.uri.parser.UriParserException;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class UriEdmValidatorTest {
|
||||||
|
|
||||||
|
private static final String URI_ALL = "$all";
|
||||||
|
private static final String URI_BATCH = "$batch";
|
||||||
|
private static final String URI_CROSSJOIN = "$crossjoin(ESAllPrim)";
|
||||||
|
private static final String URI_ENTITY_ID = "/$entity";
|
||||||
|
private static final String URI_METADATA = "$metadata";
|
||||||
|
private static final String URI_SERVICE = "";
|
||||||
|
private static final String URI_ENTITY_SET = "/ESAllPrim";
|
||||||
|
private static final String URI_ENTITY_SET_COUNT = "/ESAllPrim/$count";
|
||||||
|
private static final String URI_ENTITY = "/ESAllPrim(1)";
|
||||||
|
private static final String URI_MEDIA_STREAM = "/ESMedia(1)/$value";
|
||||||
|
private static final String URI_REFERENCES = "/ESAllPrim/$ref";
|
||||||
|
private static final String URI_REFERENCE = "/ESAllPrim(1)/$ref";
|
||||||
|
private static final String URI_PROPERTY_COMPLEX = "/ESCompComp(1)/PropertyComplex";
|
||||||
|
private static final String URI_PROPERTY_COMPLEX_COLLECTION =
|
||||||
|
"/ESCompCollComp(1)/PropertyComplex/CollPropertyComplex";
|
||||||
|
private static final String URI_PROPERTY_COMPLEX_COLLECTION_COUNT =
|
||||||
|
"/ESCompCollComp(1)/PropertyComplex/CollPropertyComplex/$count";
|
||||||
|
private static final String URI_PROPERTY_PRIMITIVE = "/ESAllPrim(1)/PropertyString";
|
||||||
|
private static final String URI_PROPERTY_PRIMITIVE_COLLECTION = "/ESCollAllPrim/CollPropertyString";
|
||||||
|
private static final String URI_PROPERTY_PRIMITIVE_COLLECTION_COUNT =
|
||||||
|
"/ESCollAllPrim/CollPropertyString/$count";
|
||||||
|
private static final String URI_PROPERTY_PRIMITIVE_VALUE = "/ESAllPrim(1)/PropertyString/$value";
|
||||||
|
private static final String URI_SINGLETON = "/SI";
|
||||||
|
private static final String URI_NAV_ENTITY = "/ESKeyNav/NavPropertyETKeyNavOne";
|
||||||
|
private static final String URI_NAV_ENTITY_SET = "/ESKeyNav/NavPropertyETKeyNavMany";
|
||||||
|
|
||||||
|
private static final String QO_FILTER = "$filter='1' eq '1'";
|
||||||
|
private static final String QO_FORMAT = "$format=bla";
|
||||||
|
private static final String QO_EXPAND = "$expand=*";
|
||||||
|
private static final String QO_ID = "$id=Products(0)";
|
||||||
|
private static final String QO_COUNT = "$count";
|
||||||
|
// private static final String QO_ORDERBY = "$orderby=true";
|
||||||
|
// private static final String QO_SEARCH = "$search='bla'";
|
||||||
|
private static final String QO_SELECT = "$select=*";
|
||||||
|
private static final String QO_SKIP = "$skip=3";
|
||||||
|
private static final String QO_SKIPTOKEN = "$skiptoken=123";
|
||||||
|
private static final String QO_LEVELS = "$expand=*($levels=1)";
|
||||||
|
private static final String QO_TOP = "$top=1";
|
||||||
|
|
||||||
|
private String[][] urisWithValidSystemQueryOptions = {
|
||||||
|
{ URI_ALL, QO_FILTER, }, { URI_ALL, QO_FORMAT }, { URI_ALL, QO_EXPAND }, { URI_ALL, QO_COUNT },
|
||||||
|
/* { URI_ALL, QO_ORDERBY }, *//* { URI_ALL, QO_SEARCH }, */{ URI_ALL, QO_SELECT }, { URI_ALL, QO_SKIP },
|
||||||
|
{ URI_ALL, QO_SKIPTOKEN }, { URI_ALL, QO_LEVELS },
|
||||||
|
|
||||||
|
{ URI_CROSSJOIN, QO_FILTER, }, { URI_CROSSJOIN, QO_FORMAT },
|
||||||
|
{ URI_CROSSJOIN, QO_EXPAND }, { URI_CROSSJOIN, QO_COUNT }, /* { URI_CROSSJOIN, QO_ORDERBY }, */
|
||||||
|
/* { URI_CROSSJOIN, QO_SEARCH }, */{ URI_CROSSJOIN, QO_SELECT }, { URI_CROSSJOIN, QO_SKIP },
|
||||||
|
{ URI_CROSSJOIN, QO_SKIPTOKEN }, { URI_CROSSJOIN, QO_LEVELS }, { URI_CROSSJOIN, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_ENTITY_ID, QO_ID, QO_FORMAT }, { URI_ENTITY_ID, QO_ID, }, { URI_ENTITY_ID, QO_ID, QO_EXPAND },
|
||||||
|
{ URI_ENTITY_ID, QO_ID, QO_SELECT }, { URI_ENTITY_ID, QO_ID, QO_LEVELS },
|
||||||
|
|
||||||
|
{ URI_METADATA, QO_FORMAT },
|
||||||
|
|
||||||
|
{ URI_SERVICE, QO_FORMAT },
|
||||||
|
|
||||||
|
{ URI_ENTITY_SET, QO_FILTER, }, { URI_ENTITY_SET, QO_FORMAT }, { URI_ENTITY_SET, QO_EXPAND },
|
||||||
|
{ URI_ENTITY_SET, QO_COUNT }, /* { URI_ENTITY_SET, QO_ORDERBY }, *//* { URI_ENTITY_SET, QO_SEARCH }, */
|
||||||
|
{ URI_ENTITY_SET, QO_SELECT },
|
||||||
|
{ URI_ENTITY_SET, QO_SKIP }, { URI_ENTITY_SET, QO_SKIPTOKEN }, { URI_ENTITY_SET, QO_LEVELS },
|
||||||
|
{ URI_ENTITY_SET, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_ENTITY, QO_FORMAT }, { URI_ENTITY, QO_EXPAND }, { URI_ENTITY, QO_SELECT }, { URI_ENTITY, QO_LEVELS },
|
||||||
|
|
||||||
|
{ URI_MEDIA_STREAM, QO_FORMAT },
|
||||||
|
|
||||||
|
{ URI_REFERENCES, QO_FILTER }, { URI_REFERENCES, QO_FORMAT }, /* { URI_REFERENCES, QO_ORDERBY }, */
|
||||||
|
/* { URI_REFERENCES, QO_SEARCH }, */{ URI_REFERENCES, QO_SKIP }, { URI_REFERENCES, QO_SKIPTOKEN },
|
||||||
|
{ URI_REFERENCES, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_REFERENCE, QO_FORMAT },
|
||||||
|
|
||||||
|
{ URI_PROPERTY_COMPLEX, QO_FORMAT }, { URI_PROPERTY_COMPLEX, QO_SELECT }, { URI_PROPERTY_COMPLEX, QO_EXPAND },
|
||||||
|
{ URI_PROPERTY_COMPLEX, QO_LEVELS },
|
||||||
|
|
||||||
|
{ URI_PROPERTY_COMPLEX_COLLECTION, QO_FILTER }, { URI_PROPERTY_COMPLEX_COLLECTION, QO_FORMAT },
|
||||||
|
{ URI_PROPERTY_COMPLEX_COLLECTION, QO_EXPAND }, { URI_PROPERTY_COMPLEX_COLLECTION, QO_COUNT },
|
||||||
|
{ URI_PROPERTY_COMPLEX_COLLECTION, QO_SKIP }, { URI_PROPERTY_COMPLEX_COLLECTION, QO_SKIPTOKEN },
|
||||||
|
{ URI_PROPERTY_COMPLEX_COLLECTION, QO_LEVELS }, { URI_PROPERTY_COMPLEX_COLLECTION, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_PROPERTY_PRIMITIVE, QO_FORMAT },
|
||||||
|
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_COLLECTION, QO_FILTER }, { URI_PROPERTY_PRIMITIVE_COLLECTION, QO_FORMAT },
|
||||||
|
/* { URI_PROPERTY_PRIMITIVE_COLLECTION, QO_ORDERBY }, */{ URI_PROPERTY_PRIMITIVE_COLLECTION, QO_SKIP },
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_COLLECTION, QO_SKIPTOKEN }, { URI_PROPERTY_PRIMITIVE_COLLECTION, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_VALUE, QO_FORMAT },
|
||||||
|
|
||||||
|
{ URI_SINGLETON, QO_FORMAT }, { URI_SINGLETON, QO_EXPAND }, { URI_SINGLETON, QO_SELECT },
|
||||||
|
{ URI_SINGLETON, QO_LEVELS },
|
||||||
|
|
||||||
|
{ URI_NAV_ENTITY, QO_FORMAT }, { URI_NAV_ENTITY, QO_EXPAND }, { URI_NAV_ENTITY, QO_SELECT },
|
||||||
|
{ URI_NAV_ENTITY, QO_LEVELS },
|
||||||
|
|
||||||
|
{ URI_NAV_ENTITY_SET, QO_FILTER, }, { URI_NAV_ENTITY_SET, QO_FORMAT }, { URI_NAV_ENTITY_SET, QO_EXPAND },
|
||||||
|
{ URI_NAV_ENTITY_SET, QO_COUNT }, /* { URI_NAV_ENTITY_SET, QO_ORDERBY }, */
|
||||||
|
/* { URI_NAV_ENTITY_SET, QO_SEARCH }, */{ URI_NAV_ENTITY_SET, QO_SELECT }, { URI_NAV_ENTITY_SET, QO_SKIP },
|
||||||
|
{ URI_NAV_ENTITY_SET, QO_SKIPTOKEN }, { URI_NAV_ENTITY_SET, QO_LEVELS }, { URI_NAV_ENTITY_SET, QO_TOP },
|
||||||
|
|
||||||
|
{ "FINRTInt16()" },
|
||||||
|
{ "FICRTETKeyNav()" },
|
||||||
|
{ "FICRTESTwoKeyNavParam(ParameterInt16=1)" },
|
||||||
|
{ "FICRTCollString()" },
|
||||||
|
{ "FICRTCTTwoPrim()" },
|
||||||
|
{ "FICRTCollCTTwoPrim()" },
|
||||||
|
{ "FICRTETMedia()" },
|
||||||
|
|
||||||
|
{ "ESTwoKeyNav/com.sap.odata.test1.BAESTwoKeyNavRTESTwoKeyNav" },
|
||||||
|
{ "ESAllPrim/com.sap.odata.test1.BAESAllPrimRTETAllPrim" },
|
||||||
|
{ "AIRTPrimCollParam" },
|
||||||
|
{ "AIRTETParam" },
|
||||||
|
{ "AIRTPrimParam" },
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
private String[][] urisWithNonValidSystemQueryOptions = {
|
||||||
|
{ URI_ALL, QO_ID, }, { URI_ALL, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_BATCH, QO_FILTER, }, { URI_BATCH, QO_FORMAT }, { URI_BATCH, QO_ID, }, { URI_BATCH, QO_EXPAND },
|
||||||
|
{ URI_BATCH, QO_COUNT }, /* { URI_BATCH, QO_ORDERBY }, *//* { URI_BATCH, QO_SEARCH }, */{ URI_BATCH, QO_SELECT },
|
||||||
|
{ URI_BATCH, QO_SKIP }, { URI_BATCH, QO_SKIPTOKEN }, { URI_BATCH, QO_LEVELS }, { URI_BATCH, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_CROSSJOIN, QO_ID, },
|
||||||
|
|
||||||
|
{ URI_ENTITY_ID, QO_ID, QO_FILTER, },
|
||||||
|
{ URI_ENTITY_ID, QO_ID, QO_COUNT }, /* { URI_ENTITY_ID, QO_ORDERBY }, *//* { URI_ENTITY_ID, QO_SEARCH }, */
|
||||||
|
|
||||||
|
{ URI_ENTITY_ID, QO_ID, QO_SKIP }, { URI_ENTITY_ID, QO_ID, QO_SKIPTOKEN }, { URI_ENTITY_ID, QO_ID, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_METADATA, QO_FILTER, }, { URI_METADATA, QO_ID, }, { URI_METADATA, QO_EXPAND },
|
||||||
|
{ URI_METADATA, QO_COUNT }, /* { URI_METADATA, QO_ORDERBY }, *//* { URI_METADATA, QO_SEARCH }, */
|
||||||
|
{ URI_METADATA, QO_SELECT }, { URI_METADATA, QO_SKIP }, { URI_METADATA, QO_SKIPTOKEN },
|
||||||
|
{ URI_METADATA, QO_LEVELS }, { URI_METADATA, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_SERVICE, QO_FILTER }, { URI_SERVICE, QO_ID }, { URI_SERVICE, QO_EXPAND }, { URI_SERVICE, QO_COUNT },
|
||||||
|
/* { URI_SERVICE, QO_ORDERBY }, *//* { URI_SERVICE, QO_SEARCH }, */{ URI_SERVICE, QO_SELECT },
|
||||||
|
{ URI_SERVICE, QO_SKIP }, { URI_SERVICE, QO_SKIPTOKEN }, { URI_SERVICE, QO_LEVELS }, { URI_SERVICE, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_ENTITY_SET, QO_ID },
|
||||||
|
|
||||||
|
{ URI_ENTITY_SET_COUNT, QO_FILTER }, { URI_ENTITY_SET_COUNT, QO_FORMAT }, { URI_ENTITY_SET_COUNT, QO_ID },
|
||||||
|
{ URI_ENTITY_SET_COUNT, QO_EXPAND }, { URI_ENTITY_SET_COUNT, QO_COUNT },
|
||||||
|
/* { URI_ENTITY_SET_COUNT, QO_ORDERBY }, *//* { URI_ENTITY_SET_COUNT, QO_SEARCH }, */
|
||||||
|
{ URI_ENTITY_SET_COUNT, QO_SELECT }, { URI_ENTITY_SET_COUNT, QO_SKIP }, { URI_ENTITY_SET_COUNT, QO_SKIPTOKEN },
|
||||||
|
{ URI_ENTITY_SET_COUNT, QO_LEVELS }, { URI_ENTITY_SET_COUNT, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_ENTITY, QO_FILTER }, { URI_ENTITY, QO_ID }, { URI_ENTITY, QO_COUNT }, /* { URI_ENTITY, QO_ORDERBY }, */
|
||||||
|
/* { URI_ENTITY, QO_SEARCH }, */{ URI_ENTITY, QO_SKIP }, { URI_ENTITY, QO_SKIPTOKEN }, { URI_ENTITY, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_MEDIA_STREAM, QO_FILTER }, { URI_MEDIA_STREAM, QO_ID, }, { URI_MEDIA_STREAM, QO_EXPAND },
|
||||||
|
{ URI_MEDIA_STREAM, QO_COUNT }, /* { URI_MEDIA_STREAM, QO_ORDERBY }, *//* { URI_MEDIA_STREAM, QO_SEARCH }, */
|
||||||
|
{ URI_MEDIA_STREAM, QO_SELECT }, { URI_MEDIA_STREAM, QO_SKIP }, { URI_MEDIA_STREAM, QO_SKIPTOKEN },
|
||||||
|
{ URI_MEDIA_STREAM, QO_LEVELS }, { URI_MEDIA_STREAM, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_REFERENCES, QO_ID, }, { URI_REFERENCES, QO_EXPAND }, { URI_REFERENCES, QO_COUNT },
|
||||||
|
{ URI_REFERENCES, QO_SELECT }, { URI_REFERENCES, QO_LEVELS },
|
||||||
|
|
||||||
|
{ URI_REFERENCE, QO_FILTER }, { URI_REFERENCE, QO_ID, }, { URI_REFERENCE, QO_EXPAND },
|
||||||
|
{ URI_REFERENCE, QO_COUNT }, /* { URI_REFERENCE, QO_ORDERBY }, *//* { URI_REFERENCE, QO_SEARCH }, */
|
||||||
|
{ URI_REFERENCE, QO_SELECT }, { URI_REFERENCE, QO_SKIP }, { URI_REFERENCE, QO_SKIPTOKEN },
|
||||||
|
{ URI_REFERENCE, QO_LEVELS }, { URI_REFERENCE, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_PROPERTY_COMPLEX, QO_FILTER }, { URI_PROPERTY_COMPLEX, QO_ID, }, { URI_PROPERTY_COMPLEX, QO_COUNT },
|
||||||
|
/* { URI_PROPERTY_COMPLEX, QO_ORDERBY }, *//* { URI_PROPERTY_COMPLEX, QO_SEARCH }, */
|
||||||
|
{ URI_PROPERTY_COMPLEX, QO_SKIP }, { URI_PROPERTY_COMPLEX, QO_SKIPTOKEN }, { URI_PROPERTY_COMPLEX, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_PROPERTY_COMPLEX_COLLECTION, QO_ID, }, /* { URI_PROPERTY_COMPLEX_COLLECTION, QO_ORDERBY }, */
|
||||||
|
/* { URI_PROPERTY_COMPLEX_COLLECTION, QO_SEARCH }, */{ URI_PROPERTY_COMPLEX_COLLECTION, QO_SELECT },
|
||||||
|
|
||||||
|
{ URI_PROPERTY_COMPLEX_COLLECTION_COUNT, QO_FILTER }, { URI_PROPERTY_COMPLEX_COLLECTION_COUNT, QO_FORMAT },
|
||||||
|
{ URI_PROPERTY_COMPLEX_COLLECTION_COUNT, QO_ID, }, { URI_PROPERTY_COMPLEX_COLLECTION_COUNT, QO_EXPAND },
|
||||||
|
{ URI_PROPERTY_COMPLEX_COLLECTION_COUNT, QO_COUNT }, /* { URI_PROPERTY_COMPLEX_COLLECTION_COUNT, QO_ORDERBY }, */
|
||||||
|
/* { URI_PROPERTY_COMPLEX_COLLECTION_COUNT, QO_SEARCH }, */{ URI_PROPERTY_COMPLEX_COLLECTION_COUNT, QO_SELECT },
|
||||||
|
{ URI_PROPERTY_COMPLEX_COLLECTION_COUNT, QO_SKIP }, { URI_PROPERTY_COMPLEX_COLLECTION_COUNT, QO_SKIPTOKEN },
|
||||||
|
{ URI_PROPERTY_COMPLEX_COLLECTION_COUNT, QO_LEVELS }, { URI_PROPERTY_COMPLEX_COLLECTION_COUNT, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_PROPERTY_PRIMITIVE, QO_FILTER }, { URI_PROPERTY_PRIMITIVE, QO_ID, }, { URI_PROPERTY_PRIMITIVE, QO_EXPAND },
|
||||||
|
{ URI_PROPERTY_PRIMITIVE, QO_COUNT }, /* { URI_PROPERTY_PRIMITIVE, QO_ORDERBY }, */
|
||||||
|
/* { URI_PROPERTY_PRIMITIVE, QO_SEARCH }, */{ URI_PROPERTY_PRIMITIVE, QO_SELECT },
|
||||||
|
{ URI_PROPERTY_PRIMITIVE, QO_SKIP }, { URI_PROPERTY_PRIMITIVE, QO_SKIPTOKEN },
|
||||||
|
{ URI_PROPERTY_PRIMITIVE, QO_LEVELS }, { URI_PROPERTY_PRIMITIVE, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_COLLECTION, QO_ID, }, { URI_PROPERTY_PRIMITIVE_COLLECTION, QO_EXPAND },
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_COLLECTION, QO_COUNT }, /* { URI_PROPERTY_PRIMITIVE_COLLECTION, QO_SEARCH }, */
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_COLLECTION, QO_SELECT }, { URI_PROPERTY_PRIMITIVE_COLLECTION, QO_LEVELS },
|
||||||
|
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_COLLECTION_COUNT, QO_FILTER }, { URI_PROPERTY_PRIMITIVE_COLLECTION_COUNT, QO_FORMAT },
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_COLLECTION_COUNT, QO_ID, }, { URI_PROPERTY_PRIMITIVE_COLLECTION_COUNT, QO_EXPAND },
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_COLLECTION_COUNT, QO_COUNT },
|
||||||
|
/* { URI_PROPERTY_PRIMITIVE_COLLECTION_COUNT, QO_ORDERBY }, */
|
||||||
|
/* { URI_PROPERTY_PRIMITIVE_COLLECTION_COUNT, QO_SEARCH }, */
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_COLLECTION_COUNT, QO_SELECT }, { URI_PROPERTY_PRIMITIVE_COLLECTION_COUNT, QO_SKIP },
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_COLLECTION_COUNT, QO_SKIPTOKEN },
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_COLLECTION_COUNT, QO_LEVELS }, { URI_PROPERTY_PRIMITIVE_COLLECTION_COUNT, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_VALUE, QO_FILTER }, { URI_PROPERTY_PRIMITIVE_VALUE, QO_ID, },
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_VALUE, QO_EXPAND }, { URI_PROPERTY_PRIMITIVE_VALUE, QO_COUNT },
|
||||||
|
/* { URI_PROPERTY_PRIMITIVE_VALUE, QO_ORDERBY }, *//* { URI_PROPERTY_PRIMITIVE_VALUE, QO_SEARCH }, */
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_VALUE, QO_SELECT }, { URI_PROPERTY_PRIMITIVE_VALUE, QO_SKIP },
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_VALUE, QO_SKIPTOKEN }, { URI_PROPERTY_PRIMITIVE_VALUE, QO_LEVELS },
|
||||||
|
{ URI_PROPERTY_PRIMITIVE_VALUE, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_SINGLETON, QO_FILTER }, { URI_SINGLETON, QO_ID }, { URI_SINGLETON, QO_COUNT },
|
||||||
|
/* { URI_SINGLETON, QO_ORDERBY }, *//* { URI_SINGLETON, QO_SEARCH }, */{ URI_SINGLETON, QO_SKIP },
|
||||||
|
{ URI_SINGLETON, QO_SKIPTOKEN }, { URI_SINGLETON, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_NAV_ENTITY, QO_FILTER }, { URI_NAV_ENTITY, QO_ID }, { URI_NAV_ENTITY, QO_COUNT },
|
||||||
|
/* { URI_NAV_ENTITY, QO_ORDERBY }, *//* { URI_NAV_ENTITY, QO_SEARCH }, */{ URI_NAV_ENTITY, QO_SKIP },
|
||||||
|
{ URI_NAV_ENTITY, QO_SKIPTOKEN }, { URI_SINGLETON, QO_TOP },
|
||||||
|
|
||||||
|
{ URI_NAV_ENTITY_SET, QO_ID },
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
private Parser parser;
|
||||||
|
private Edm edm;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
parser = new Parser();
|
||||||
|
edm = new EdmProviderImpl(new EdmTechProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = UriValidationException.class)
|
||||||
|
public void validateKeyPredicatesWrongKey() throws Exception {
|
||||||
|
String uri = "ESTwoKeyNav(xxx=1, yyy='abc')";
|
||||||
|
parseAndValidate(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateKeyPredicates() throws Exception {
|
||||||
|
String uri = "ESTwoKeyNav(PropertyInt16=1, PropertyString='abc')";
|
||||||
|
parseAndValidate(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = UriValidationException.class)
|
||||||
|
public void validateKeyPredicatesWrongValueType() throws Exception {
|
||||||
|
String uri = "ESTwoKeyNav(PropertyInt16='abc', PropertyString=1)";
|
||||||
|
parseAndValidate(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkValidSystemQueryOption() throws Exception {
|
||||||
|
String[] uris = constructUri(urisWithValidSystemQueryOptions);
|
||||||
|
|
||||||
|
for (String uri : uris) {
|
||||||
|
try {
|
||||||
|
parseAndValidate(uri);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new Exception("Faild for uri: " + uri, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void checkNonValidSystemQueryOption() throws Exception {
|
||||||
|
String[] uris = constructUri(urisWithNonValidSystemQueryOptions);
|
||||||
|
|
||||||
|
for (String uri : uris) {
|
||||||
|
try {
|
||||||
|
parseAndValidate(uri);
|
||||||
|
fail("Validation Exception not thrown: " + uri);
|
||||||
|
} catch (UriValidationException e) {
|
||||||
|
assertTrue(e instanceof UriValidationException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] constructUri(String[][] uriParameterMatrix) {
|
||||||
|
ArrayList<String> uris = new ArrayList<String>();
|
||||||
|
for (String[] uriParameter : uriParameterMatrix) {
|
||||||
|
String uri = uriParameter[0];
|
||||||
|
if (uriParameter.length > 1) {
|
||||||
|
uri += "?";
|
||||||
|
}
|
||||||
|
for (int i = 1; i < uriParameter.length; i++) {
|
||||||
|
uri += uriParameter[i];
|
||||||
|
if (i < (uriParameter.length - 1)) {
|
||||||
|
uri += "&";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uris.add(uri);
|
||||||
|
}
|
||||||
|
return uris.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseAndValidate(String uri) throws UriParserException, UriValidationException {
|
||||||
|
UriInfo uriInfo = parser.parseUri(uri.trim(), edm);
|
||||||
|
UriValidator validator = new UriValidator();
|
||||||
|
|
||||||
|
validator.validate(uriInfo, edm, "GET");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue