blob: 82beaca53c11025d9a474ba4b610dcdf82308a66 [file] [log] [blame]
/*
* 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.serializer.utils;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceAction;
import org.apache.olingo.server.api.uri.UriResourceComplexProperty;
import org.apache.olingo.server.api.uri.UriResourceCount;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.UriResourceFunction;
import org.apache.olingo.server.api.uri.UriResourceNavigation;
import org.apache.olingo.server.api.uri.UriResourceProperty;
import org.apache.olingo.server.api.uri.UriResourceRef;
import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
import org.apache.olingo.server.api.uri.queryoption.SelectItem;
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
public abstract class ExpandSelectHelper {
public static boolean hasSelect(final SelectOption select) {
return select != null && select.getSelectItems() != null && !select.getSelectItems().isEmpty();
}
public static boolean isAll(final SelectOption select) {
if (hasSelect(select)) {
for (final SelectItem item : select.getSelectItems()) {
if (item.isStar()) {
return true;
}
}
return false;
} else {
return true;
}
}
public static Set<String> getSelectedPropertyNames(final List<SelectItem> selectItems) {
Set<String> selected = new HashSet<>();
for (final SelectItem item : selectItems) {
final UriResource resource = item.getResourcePath().getUriResourceParts().get(0);
if (resource instanceof UriResourceProperty) {
selected.add(((UriResourceProperty) resource).getProperty().getName());
} else if (resource instanceof UriResourceNavigation) {
selected.add(((UriResourceNavigation) resource).getProperty().getName());
} else if (resource instanceof UriResourceAction) {
selected.add(((UriResourceAction) resource).getAction().getName());
} else if (resource instanceof UriResourceFunction) {
selected.add(((UriResourceFunction) resource).getFunction().getName());
}
}
return selected;
}
/**
* This method creates selectedPath list checking if the resource has entity type filter,
* complex type filter, or if resource is navigation property and if it has type filter
* @param selectItems items in the select clause
* @param propertyName propertyName
* @return Set<List<String>> return a list of selected paths
*/
public static Set<List<String>> getSelectedPathsWithTypeCasts(
final List<SelectItem> selectItems, final String propertyName) {
Set<List<String>> selectedPaths = new HashSet<>();
for (final SelectItem item : selectItems) {
final List<UriResource> parts = item.getResourcePath().getUriResourceParts();
final UriResource resource = parts.get(0);
if (resource instanceof UriResourceProperty
&& propertyName.equals(((UriResourceProperty) resource).getProperty().getName())) {
List<String> path = new ArrayList<>();
if (item.getStartTypeFilter() != null) {
path.add(item.getStartTypeFilter().getFullQualifiedName().getFullQualifiedNameAsString());
}
if (resource instanceof UriResourceComplexProperty &&
((UriResourceComplexProperty) resource).getComplexTypeFilter() != null) {
path.add(((UriResourceComplexProperty) resource).getComplexTypeFilter().
getFullQualifiedName().getFullQualifiedNameAsString());
} else if (resource instanceof UriResourceEntitySet &&
((UriResourceEntitySet) resource).getTypeFilterOnCollection() != null) {
path.add(((UriResourceEntitySet) resource).getTypeFilterOnCollection().
getFullQualifiedName().getFullQualifiedNameAsString());
}
extractPathsFromResourceParts(selectedPaths, parts, path);
} else if (resource instanceof UriResourceNavigation
&& propertyName.equals(((UriResourceNavigation) resource).getProperty().getName()) ) {
List<String> path = new ArrayList<>();
if (item.getStartTypeFilter() != null) {
path.add(item.getStartTypeFilter().getFullQualifiedName().getFullQualifiedNameAsString());
}
extractPathsFromResourceParts(selectedPaths, parts, path);
}
}
return selectedPaths.isEmpty() ? null : selectedPaths;
}
/**
* @param selectedPaths
* @param parts
* @param path
*/
private static Set<List<String>> extractPathsFromResourceParts(
Set<List<String>> selectedPaths, final List<UriResource> parts,
List<String> path) {
if (parts.size() > 1) {
for (final UriResource part : parts.subList(1, parts.size())) {
if (part instanceof UriResourceProperty) {
path.add(((UriResourceProperty) part).getProperty().getName());
} else if (part instanceof UriResourceNavigation) {
path.add(((UriResourceNavigation) part).getProperty().getName());
}
if (part instanceof UriResourceComplexProperty &&
((UriResourceComplexProperty) part).getComplexTypeFilter() != null) {
path.add(((UriResourceComplexProperty) part).getComplexTypeFilter().
getFullQualifiedName().getFullQualifiedNameAsString());
}
}
selectedPaths.add(path);
} else if (!path.isEmpty()) {
selectedPaths.add(path);
} else {
return null;
}
return selectedPaths.isEmpty() ? null : selectedPaths;
}
public static Set<List<String>> getSelectedPaths(final List<SelectItem> selectItems, final String propertyName) {
Set<List<String>> selectedPaths = new HashSet<>();
for (final SelectItem item : selectItems) {
final List<UriResource> parts = item.getResourcePath().getUriResourceParts();
final UriResource resource = parts.get(0);
if (resource instanceof UriResourceProperty
&& propertyName.equals(((UriResourceProperty) resource).getProperty().getName())) {
if (parts.size() > 1) {
List<String> path = new ArrayList<>();
for (final UriResource part : parts.subList(1, parts.size())) {
if (part instanceof UriResourceProperty) {
path.add(((UriResourceProperty) part).getProperty().getName());
} else if (part instanceof UriResourceNavigation) {
path.add(((UriResourceNavigation) part).getProperty().getName());
}
}
selectedPaths.add(path);
} else {
return null;
}
}
}
return selectedPaths.isEmpty() ? null : selectedPaths;
}
public static Set<List<String>> getSelectedPaths(final List<SelectItem> selectItems) {
Set<List<String>> selectedPaths = new HashSet<>();
for (final SelectItem item : selectItems) {
final List<UriResource> parts = item.getResourcePath().getUriResourceParts();
final UriResource resource = parts.get(0);
if (resource instanceof UriResourceProperty) {
if (!parts.isEmpty()) {
List<String> path = new ArrayList<>();
for (final UriResource part : parts.subList(0, parts.size())) {
if (part instanceof UriResourceProperty) {
path.add(((UriResourceProperty) part).getProperty().getName());
}
}
selectedPaths.add(path);
} else {
return null;
}
}
}
return selectedPaths.isEmpty() ? null : selectedPaths;
}
public static boolean isSelected(final Set<List<String>> selectedPaths, final String propertyName) {
for (final List<String> path : selectedPaths) {
if (propertyName.equals(path.get(0))) {
return true;
}
}
return false;
}
public static Set<List<String>> getReducedSelectedPaths(final Set<List<String>> selectedPaths,
final String propertyName) {
Set<List<String>> reducedPaths = new HashSet<>();
for (final List<String> path : selectedPaths) {
if (propertyName.equals(path.get(0))) {
if (path.size() > 1) {
reducedPaths.add(path.subList(1, path.size()));
} else {
return null;
}
}
}
return reducedPaths.isEmpty() ? null : reducedPaths;
}
public static boolean hasExpand(final ExpandOption expand) {
return expand != null && expand.getExpandItems() != null && !expand.getExpandItems().isEmpty();
}
public static ExpandItem getExpandAll(final ExpandOption expand) {
for (final ExpandItem item : expand.getExpandItems()) {
if (item.isStar()) {
return item;
}
}
return null;
}
public static Set<String> getExpandedPropertyNames(final List<ExpandItem> expandItems)
throws SerializerException {
Set<String> expanded = new HashSet<>();
for (final ExpandItem item : expandItems) {
final List<UriResource> resourceParts = item.getResourcePath().getUriResourceParts();
final UriResource resource = resourceParts.get(0);
if (resource instanceof UriResourceNavigation) {
expanded.add(((UriResourceNavigation) resource).getProperty().getName());
}
}
return expanded;
}
public static ExpandItem getExpandItem(final List<ExpandItem> expandItems, final String propertyName) {
for (final ExpandItem item : expandItems) {
if (item.isStar()) {
continue;
}
final List<UriResource> resourceParts = item.getResourcePath().getUriResourceParts();
UriResource resource = null;
if (resourceParts.get(resourceParts.size() - 1) instanceof UriResourceRef ||
resourceParts.get(resourceParts.size() - 1) instanceof UriResourceCount) {
resource = resourceParts.get(resourceParts.size() - 2);
} else {
resource = resourceParts.get(resourceParts.size() - 1);
}
if ((resource instanceof UriResourceNavigation
&& propertyName.equals(((UriResourceNavigation) resource).getProperty().getName())) ||
resource instanceof UriResourceProperty
&& propertyName.equals(((UriResourceProperty) resource).getProperty().getName())) {
return item;
}
}
return null;
}
public static Set<List<String>> getExpandedItemsPath(ExpandOption expand) {
Set<List<String>> expandPaths = new HashSet<>();
if (expand != null) {
List<ExpandItem> expandItems = expand.getExpandItems();
for (ExpandItem item : expandItems) {
if (item.isStar()) {
continue;
}
List<UriResource> resourceParts = item.getResourcePath().getUriResourceParts();
if (resourceParts.get(0) instanceof UriResourceComplexProperty) {
List<String> path = new ArrayList<>();
for (UriResource resource : resourceParts) {
if (resource instanceof UriResourceNavigation) {
path.add(((UriResourceNavigation) resource).getProperty().getName());
} else if (resource instanceof UriResourceProperty) {
path.add(((UriResourceProperty) resource).getProperty().getName());
}
}
expandPaths.add(path);
}
}
}
return expandPaths;
}
public static Set<List<String>> getReducedExpandItemsPaths(final Set<List<String>> expandItemsPaths,
final String propertyName) {
Set<List<String>> reducedPaths = new HashSet<>();
for (final List<String> path : expandItemsPaths) {
if (propertyName.equals(path.get(0))) {
if (path.size() > 1) {
reducedPaths.add(path.subList(1, path.size()));
}
} else {
reducedPaths.add(path);
}
}
return reducedPaths.isEmpty() ? null : reducedPaths;
}
/**
* Fetches the expand Item depending upon the type
* @param expandItems
* @param propertyName
* @param type
* @param resourceName
* @return
*/
public static ExpandItem getExpandItemBasedOnType(final List<ExpandItem> expandItems,
final String propertyName, final EdmStructuredType type, String resourceName) {
ExpandItem expandItem = null;
for (final ExpandItem item : expandItems) {
boolean matched = false;
if (item.isStar()) {
continue;
}
final List<UriResource> resourceParts = item.getResourcePath().getUriResourceParts();
UriResource resource = null;
if (resourceParts.size() == 1) {
resource = resourceParts.get(0);
matched = true;
expandItem = getMatchedExpandItem(propertyName, item, matched, resource);
} else if (resourceParts.get(resourceParts.size() - 1) instanceof UriResourceRef ||
resourceParts.get(resourceParts.size() - 1) instanceof UriResourceCount) {
if (resourceParts.size() == 2) {
resource = resourceParts.get(0);
matched = true;
expandItem = getMatchedExpandItem(propertyName, item, matched, resource);
} else {
resource = resourceParts.get(resourceParts.size() - 3);
matched = resource.getSegmentValue().equalsIgnoreCase(resourceName) ?
isFoundExpandItem(type, matched, resource) : false;
expandItem = getMatchedExpandItem(propertyName, item, matched, resourceParts.get(resourceParts.size() - 2));
}
} else {
resource = resourceParts.get(resourceParts.size() - 2);
matched = resource.getSegmentValue().equalsIgnoreCase(resourceName) ?
isFoundExpandItem(type, matched, resource) : false;
expandItem = getMatchedExpandItem(propertyName, item, matched, resourceParts.get(resourceParts.size() - 1));
}
if (expandItem != null) {
return expandItem;
}
}
return expandItem;
}
/**
* @param propertyName
* @param item
* @param matched
* @param resource
*/
private static ExpandItem getMatchedExpandItem(final String propertyName, final ExpandItem item, boolean matched,
UriResource resource) {
if (matched && ((resource instanceof UriResourceNavigation
&& propertyName.equals(((UriResourceNavigation) resource).getProperty().getName())) ||
resource instanceof UriResourceProperty
&& propertyName.equals(((UriResourceProperty) resource).getProperty().getName()))) {
return item;
}
return null;
}
/**
* @param type
* @param matched
* @param resource
* @return
*/
private static boolean isFoundExpandItem(final EdmStructuredType type,
boolean matched, UriResource resource) {
if (!matched) {
if ((resource instanceof UriResourceProperty &&
type.compatibleTo(((UriResourceProperty) resource).getType())) ||
(resource instanceof UriResourceNavigation &&
type.compatibleTo(((UriResourceNavigation) resource).getType()))) {
matched = true;
}
}
return matched;
}
}