Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*******************************************************************************
* (c) 201X SAP SE or an SAP affiliate company. All rights reserved.
******************************************************************************/
package com.sap.cloud.sdk.odatav2.connectivity;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.olingo.odata2.api.edm.EdmEntityType;
import org.apache.olingo.odata2.api.edm.EdmException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sap.cloud.sdk.cloudplatform.cache.CacheKey;
import com.sap.cloud.sdk.odatav2.connectivity.api.IQueryBuilder;
import com.sap.cloud.sdk.odatav2.connectivity.impl.ODataQueryImpl;
import lombok.Setter;
import lombok.experimental.Accessors;
@Accessors(chain = true, fluent = true)
public final class ODataQueryBuilder implements IQueryBuilder{
final static Logger logger = LoggerFactory.getLogger(ODataQueryBuilder.class);
public static final char QUERY_PARAM_SEPARATOR = '&';
private final String servicePath;
private final String entity;
@Setter
private ErrorResultHandler> errorHandler;
private Map headers = new HashMap();
private Map destinationRelevantHeaders = new HashMap();
private List navigationProperties = new ArrayList();
private ODataNavigationRequest navigationProperty;
private Number top;
private Number skip;
String inlineCount = null;
// @Setter
// private String id = null;
private boolean useMetadata = true;
private final Map queryParams = Maps.newHashMap();
private final List selects = Lists.newArrayList();
private final List filters = Lists.newArrayList();
private final List expands = Lists.newArrayList();
private Map keys;
// this variable is true is metadata cache is enabled.
private boolean cacheMetadata = false;
// this variable have the cacheKey value.
private CacheKey cacheKey;
private boolean isCacheRefresh = false;
private URL metadataFilePath;
private ODataQueryBuilder(String servicePath, String entity) {
this.servicePath = servicePath;
this.entity = entity;
}
/**
* Creates an ODataQueryBuilder with the given service and entity name.
*
* @param serviceName name of the odata service where the developer wants to
* execute a query operation.
* @param entitySetName name of the entity set, on which the developer wants to
* execute a query operation.
* @return ODataQueryBuilder
*/
public static ODataQueryBuilder withEntity(String servicePath, String entity) {
return new ODataQueryBuilder(servicePath, entity);
}
/**
* Selects properties to read.
*
* @param selects The list of properties to be read.
* @return ODataQueryBuilder
*/
public ODataQueryBuilder select(final String... selects) {
Collections.addAll(this.selects, selects);
return this;
}
/**
* Selects properties to read.
*
* @param selects of type List- The list of properties to be read.
* @return ODataQueryBuilder
*/
public ODataQueryBuilder select(final List selects) {
String[] s = selects.toArray(new String[selects.size()]);
Collections.addAll(this.selects, s);
return this;
}
/**
* Enables caching of the metadata of an OData V2 data source. If your
* application is running on a tenant, then the tenant ID along with the
* metadata URL is used to form the cache key.
*
* @return ODataQueryBuilder
*/
public ODataQueryBuilder enableMetadataCache() {
this.cacheMetadata = true;
return this;
}
/**
* Enables caching of the metadata of an OData V2 data source.
*
* @param key {@link com.sap.cloud.sdk.cloudplatform.cache.CacheKey Cache key}
* containing the ID of the tenant where the application runs. You
* can also include the user name in the cache key.
* @return ODataQueryBuilder
*/
public ODataQueryBuilder enableMetadataCache(CacheKey cacheKey) {
this.cacheKey = cacheKey;
this.cacheMetadata = true;
return this;
}
/**
* Replaces the existing metadata in the cache with the latest version from the
* OData V2 data source.
*
* @return ODataQueryBuilder
*/
public ODataQueryBuilder withCacheRefresh() {
this.isCacheRefresh = true;
return this;
}
/**
* Gets the metadata from the specified path.
*
* @param metadataFilePath URL pointing to the metadata information
* @return ODataQueryBuilder A builder for forming the Create
*/
public ODataQueryBuilder withMetadata(URL metadataFilePath) {
this.metadataFilePath = metadataFilePath;
return this;
}
/**
* Adds a header to the query request.
*
* @param key name of the header
* @param value value of the header
* @return ODataQueryBuilder
*/
public ODataQueryBuilder withHeader(String key, String value) {
return withHeader(key, value, false);
}
/**
* Adds a header to the query request and optionally to the metadata request as
* well depending on the value of the passInAllRequests parameter.
*
* @param key name of the header
* @param value value of the header
* @param passInAllRequests boolean indicating whether the header is to be
* passed in all the requests to the backend like
* $metadata call etc. made as part of the Query
* Request call.
* @return ODataQueryBuilder
*/
public ODataQueryBuilder withHeader(String key, String value, boolean passInAllRequests) {
if (passInAllRequests)
destinationRelevantHeaders.put(key, value);// These headers are added to the metadata request.
if (key.equals("SAP-PASSPORT") && !passInAllRequests)
destinationRelevantHeaders.put(key, value);// The header "SAP-PASSPORT" is added to metadata request even
// though the 'passInAllRequests' us false.
headers.put(key, value);// All headers must be considered for the actual OData operation.
return this;
}
/**
* Sets $inlinecount=allpages as a query parameter.
*
* @return ODataQueryBuilder
*/
public ODataQueryBuilder inlineCount() {
inlineCount = "allpages";
return this;
}
/**
* Selects navigation properties to expand.
*
* @param expands List of navigation properties to expand
* @return ODataQueryBuilder
*/
public ODataQueryBuilder expand(final String... expands) {
Collections.addAll(this.expands, expands);
return this;
}
/**
* Sets top value.
*
* @param n the top value required
* @return ODataQueryBuilder
*/
public ODataQueryBuilder top(Integer n) {
if (n != null && n >= 0) {
top = n;
}
return this;
}
/**
* Sets skip value.
*
* @param n the skip value required
* @return ODataQueryBuilder
*/
public ODataQueryBuilder skip(Integer n) {
if (n != null && n >= 0) {
skip = n;
}
return this;
}
/**
* Adds a Filter expression to the OData query.
*
* @param filter Object of FilterExpression that represents an OData filter
* expression.
* @return ODataQueryBuilder
*/
public final ODataQueryBuilder filter(final FilterExpression filter) {
filters.add(filter);
return this;
}
/**
* Adds a query parameter to the OData request.
*
* @param key
* @param value
* @return ODataQueryBuilder
*/
public ODataQueryBuilder param(final String key, final Object value) {
if (key.equals("$inlinecount") && value.toString().equals("allpages"))
inlineCount();
else
queryParams.put(key, value);
return this;
}
/**
* Used to tell the framework to not get the metadata before the actual query.
* This is not honoured if keys are set or if filter is set because the
* framework uses metadata for these use cases.
*
* @return
*/
public ODataQueryBuilder withoutMetadata() {
useMetadata = false;
return this;
}
/**
* Set Keys for the entity set being queried
*
* @param keys
* @return
*/
public ODataQueryBuilder keys(Map keys) {
if(navigationProperty != null){
navigationProperty.keys(keys);
}else{
this.keys = keys;
}
return this;
}
public ODataQueryBuilder useMetadata(boolean useMetadata) {
this.useMetadata = useMetadata;
return this;
}
/**
* Builds an OData query from this builder.
*
* @return ODataQuery
*/
public ODataQuery build() {
if (keys != null) // If keys is not null it means that its a READ call which does not support
// inlineCount, hence simply ignoring inlinecount.
inlineCount = null;
if (keys != null || !filters.isEmpty()) // If keys or filter is set, then we need the metadata for serialization
// hence manually setting useMetadata to true.
useMetadata = true;
return new ODataQueryImpl(servicePath, entity, keys, new ODataQueryResolver(), errorHandler, headers,
destinationRelevantHeaders, useMetadata, cacheMetadata, metadataFilePath, cacheKey,
isCacheRefresh, navigationProperties);
}
public class ODataQueryResolver {
/*
* String getPath() { if( StringUtils.isNotEmpty(id) ) { return "(" + id + ")";
* } return null; }
*/
public String getQuery() {
try {
return getQuery(null);
} catch (EdmException e) {
logger.error("Error while forming the query", e);
return null;
}
}
public String getQuery(EdmEntityType entityType) throws EdmException {
final ArrayList modifiers = new ArrayList<>();
addModifierFilter(modifiers, filters, entityType);
addModifier(modifiers, queryParams);
addModifier(modifiers, "$select", selects);
addModifier(modifiers, "$expand", expands);
addModifier(modifiers, "$top", top);
addModifier(modifiers, "$skip", skip);
addModifier(modifiers, "$format", "json");
addModifier(modifiers, "$inlinecount", inlineCount);
return StringUtils.join(modifiers, QUERY_PARAM_SEPARATOR);
}
private void addModifier(final ArrayList mods, final String label, final Object val) {
if (val != null) {
mods.add(label + "=" + val.toString());
}
}
private void addModifier(final ArrayList mods, final String label, final Iterable values) {
final StringBuilder valueBlock = new StringBuilder();
if (values != null && values.iterator().hasNext()) {
final List encodedItems = Lists.newArrayList();
for (final String val : values) {
encodedItems.add(val);
}
mods.add(label + "=" + StringUtils.join(encodedItems, ','));
}
}
private void addModifierFilter(final ArrayList mods, final List values,
EdmEntityType entityType) throws EdmException {
if (values != null) {
final Iterator iterator = values.iterator();
FilterExpression filter = null;
while (iterator.hasNext()) {
filter = filter == null ? iterator.next() : filter.and(iterator.next());
}
if (filter != null) {
addModifier(mods, "$filter", filter.toString(entityType));
}
}
}
private void addModifier(final ArrayList mods, final Map properties) {
if (properties != null) {
for (final Map.Entry property : properties.entrySet()) {
addModifier(mods, property.getKey(), property.getValue().toString());
}
}
}
}
@Override
public ODataQueryBuilder navigateTo(String navigation) {
this.navigationProperty = new ODataNavigationRequest(navigation);
navigationProperties.add(navigationProperty);
return this;
}
}