com.contentstack.sdk.Query Maven / Gradle / Ivy
Show all versions of java Show documentation
package com.contentstack.sdk;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.contentstack.sdk.Constants.*;
/**
* Contentstack provides certain queries that you can use to fetch filtered results. You can use queries for Entries
* and
* Queries Contentstack
* provides certain queries that you can use to fetch filtered results. You can use queries for Entries and Assets API
* requests.
*
* You can now pass the branch header in the API request to fetch or manage modules located within specific branches of
* the stack.
*
* Note Branches is a plan-based feature that is available only in the
* new Contentstack interface.
*
* @author Shailesh Mishra
* @version 1.0.0
* @since 01-11-2017
*/
public class Query implements INotifyClass {
protected static final Logger logger = Logger.getLogger(Query.class.getSimpleName());
protected ContentType contentTypeInstance = null;
protected LinkedHashMap headers = null;
protected JSONObject urlQueries;
protected JSONObject mainJSON;
protected String contentTypeUid;
protected QueryResultsCallBack queryResultCallback;
protected SingleQueryResultCallback singleQueryResultCallback;
protected JSONObject queryValueJSON;
protected JSONObject queryValue;
protected JSONArray objectUidForInclude = null;
protected JSONArray objectUidForExcept = null;
protected JSONArray objectUidForOnly = null;
private boolean isJsonProper = true;
private String errorString;
private JSONObject onlyJsonObject;
private JSONObject exceptJsonObject;
protected Query(String formName) {
this.contentTypeUid = formName;
this.urlQueries = new JSONObject();
this.queryValue = new JSONObject();
this.queryValueJSON = new JSONObject();
this.mainJSON = new JSONObject();
}
protected void setContentTypeInstance(ContentType contentTypeInstance) {
this.contentTypeInstance = contentTypeInstance;
}
/**
* To set headers for Built.io Contentstack rest calls.
Scope is limited to this object and followed classes.
*
* @param key header name.
* @param value header value against given header name.
*
*
*
* Example :
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
*
* Query query = stack.contentType("contentTypeUid").query(); query.setHeader("custom_key", "custom_value");
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
*
* Query csQuery = stack.contentType("contentTypeUid").query();
csQuery.setHeader("custom_key", "custom_value");
*
*/
public Query setHeader(@NotNull String key, @NotNull String value) {
if (!key.isEmpty() && !value.isEmpty()) {
this.headers.put(key, value);
}
return this;
}
/**
* Remove header key @param key custom_header_key
*
* @param key {@link String}
* Example :
*
* Stack stack = Contentstack..stack( "apiKey", "deliveryToken", "environment"); Query csQuery =
* stack.contentType("contentTypeUid").query();
csQuery.removeHeader("custom_key");
*/
public Query removeHeader(@NotNull String key) {
if (!key.isEmpty()) {
this.headers.remove(key);
}
return this;
}
public String getContentType() {
return contentTypeInstance.contentTypeUid;
}
/**
* Add a constraint to fetch all entries that contains given value against specified key
*
* @param key field uid.
* @param value field value which get 'included' from the response.
* @return {@link Query} object, so you can chain this call.
*
* Note : for group field provide key in a
* "key.groupFieldUid" format.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.where("uid", "entry_uid");
*
*/
public Query where(@NotNull String key, Object value) {
queryValueJSON.put(key, value);
return this;
}
/**
* Add a custom query against specified key.
*
* @param key key.
* @param value value.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack..stack( "apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.addQuery("query_param_key", "query_param_value");
*
*/
public Query addQuery(@NotNull String key, String value) {
if (value != null) {
urlQueries.put(key, value);
}
return this;
}
/**
* Remove provided query key from custom query if existed.
*
* @param key Query name to remove.
* @return {@linkplain Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* projectQuery.removeQuery("Query_Key");
*
*/
public Query removeQuery(@NotNull String key) {
if (urlQueries.has(key)) {
urlQueries.remove(key);
}
return this;
}
/**
* Combines all the queries together using AND operator
*
* @param queryObjects list of {@link Query} instances on which AND query executes.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example ;
*
*
* Stack stack = Contentstack..stack( "apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* Query query = projectClass.query();
* query.where('username','something');
* Query subQuery = projectClass.query();
* subQuery.where('email_address','[email protected]');
* ArrayList<Query> array = new ArrayList<Query>();
* array.add(query);
* array.add(subQuery);
* projectQuery.and(array);
*
*/
public Query and(@NotNull List queryObjects) {
if (!queryObjects.isEmpty()) {
JSONArray orValueJson = new JSONArray();
queryObjects.forEach(obj -> orValueJson.put(obj.queryValueJSON));
queryValueJSON.put("$and", orValueJson);
} else {
throwException("and", "Can not process with blank query objects", null);
}
return this;
}
/**
* Add a constraint to fetch all entries which satisfy any queries.
*
* @param queryObjects list of {@link Query} instances on which OR query executes.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* Query query = projectClass.query();
* query.where('username','something');
* Query subQuery = projectClass.query();
* subQuery.where('email_address','[email protected]');
* ArrayList<Query> array = new ArrayList<Query>();
* array.add(query);
* array.add(subQuery);
* csQuery.or(array);
*
*/
public Query or(List queryObjects) {
if (queryObjects != null && !queryObjects.isEmpty()) {
try {
JSONArray orValueJson = new JSONArray();
for (Query queryObject : queryObjects) {
orValueJson.put(queryObject.queryValueJSON);
}
queryValueJSON.put("$or", orValueJson);
} catch (Exception e) {
throwException("or", Constants.QUERY_EXCEPTION, e);
}
}
return this;
}
/**
* Add a constraint to the query that requires a particular key entry to be less than the provided value.
*
* @param key the key to be constrained.
* @param value the value that provides an upper bound.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.lessThan("due_date", "2013-06-25T00:00:00+05:30");
*
*/
public Query lessThan(@NotNull String key, @NotNull Object value) {
if (queryValueJSON.isNull(key)) {
if (!queryValue.isEmpty()) {
queryValue = new JSONObject();
}
queryValue.put("$lt", value);
queryValueJSON.put(key, queryValue);
} else if (queryValueJSON.has(key)) {
queryValue.put("$lt", value);
queryValueJSON.put(key, queryValue);
}
return this;
}
/**
* Add a constraint to the query that requires a particular key entry to be less than or equal to the provided
* value.
*
* @param key The key to be constrained
* @param value The value that must be equalled.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.lessThanOrEqualTo("due_date", "2013-06-25T00:00:00+05:30");
*
*/
public Query lessThanOrEqualTo(@NotNull String key, Object value) {
if (queryValueJSON.isNull(key)) {
if (!queryValue.isEmpty()) {
queryValue = new JSONObject();
}
queryValue.put("$lte", value);
queryValueJSON.put(key, queryValue);
} else if (queryValueJSON.has(key)) {
queryValue.put("$lte", value);
queryValueJSON.put(key, queryValue);
}
return this;
}
/**
* Add a constraint to the query that requires a particular key entry to be greater than the provided value.
*
* @param key The key to be constrained.
* @param value The value that provides a lower bound.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.greaterThan("due_date", "2013-06-25T00:00:00+05:30");
*
*/
public Query greaterThan(@NotNull String key, Object value) {
if (queryValueJSON.isNull(key)) {
if (!queryValue.isEmpty()) {
queryValue = new JSONObject();
}
queryValue.put("$gt", value);
queryValueJSON.put(key, queryValue);
} else if (queryValueJSON.has(key)) {
queryValue.put("$gt", value);
queryValueJSON.put(key, queryValue);
}
return this;
}
/**
* Add a constraint to the query that requires a particular key entry to be greater than or equal to the provided
* value.
*
* @param key The key to be constrained.
* @param value The value that provides a lower bound.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.greaterThanOrEqualTo("due_date", "2013-06-25T00:00:00+05:30");
*
*/
public Query greaterThanOrEqualTo(String key, Object value) {
if (queryValueJSON.isNull(key)) {
if (queryValue.length() > 0) {
queryValue = new JSONObject();
}
queryValue.put("$gte", value);
queryValueJSON.put(key, queryValue);
} else if (queryValueJSON.has(key)) {
queryValue.put("$gte", value);
queryValueJSON.put(key, queryValue);
}
return this;
}
/**
* Add a constraint to the query that requires a particular key's entry to be not equal to the provided value.
*
* @param key The key to be constrained.
* @param value The object that must not be equaled.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example ;
*
*
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.notEqualTo("due_date", "2013-06-25T00:00:00+05:30");
*
*/
public Query notEqualTo(@NotNull String key, Object value) {
if (queryValueJSON.isNull(key)) {
if (queryValue.length() > 0) {
queryValue = new JSONObject();
}
queryValue.put("$ne", value);
queryValueJSON.put(key, queryValue);
} else if (queryValueJSON.has(key)) {
queryValue.put("$ne", value);
queryValueJSON.put(key, queryValue);
}
return this;
}
/**
* Add a constraint to the query that requires a particular key's entry to be contained in the provided array.
*
* @param key The key to be constrained.
* @param values The possible values for the key's object.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.containedIn("severity", new Object[] { "Show Stopper", "Critical" });
*
*/
public Query containedIn(@NotNull String key, Object[] values) {
JSONArray valuesArray = new JSONArray();
for (Object value : values) {
valuesArray.put(value);
}
if (queryValueJSON.isNull(key)) {
if (queryValue.length() > 0) {
queryValue = new JSONObject();
}
queryValue.put("$in", valuesArray);
queryValueJSON.put(key, queryValue);
} else if (queryValueJSON.has(key)) {
queryValue.put("$in", valuesArray);
queryValueJSON.put(key, queryValue);
}
return this;
}
/**
* Add a constraint to the query that requires a particular key entry's value not be contained in the provided
* array.
*
* @param key The key to be constrained.
* @param values The list of values the key object should not be.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.notContainedIn("severity", new Object[] { "Show Stopper", "Critical" });
*
*/
public Query notContainedIn(@NotNull String key, Object[] values) {
JSONArray valuesArray = new JSONArray();
for (Object value : values) {
valuesArray.put(value);
}
if (queryValueJSON.isNull(key)) {
if (queryValue.length() > 0) {
queryValue = new JSONObject();
}
queryValue.put("$nin", valuesArray);
queryValueJSON.put(key, queryValue);
} else if (queryValueJSON.has(key)) {
queryValue.put("$nin", valuesArray);
queryValueJSON.put(key, queryValue);
}
return this;
}
/**
* Add a constraint that requires, a specified key exists in response.
*
* @param key The key to be constrained.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.exists("status");
*
*/
public Query exists(@NotNull String key) {
if (queryValueJSON.isNull(key)) {
if (queryValue.length() > 0) {
queryValue = new JSONObject();
}
queryValue.put(EXISTS, true);
queryValueJSON.put(key, queryValue);
} else if (queryValueJSON.has(key)) {
queryValue.put(EXISTS, true);
queryValueJSON.put(key, queryValue);
}
return this;
}
/**
* Add a constraint that requires, a specified key does not exist in response.
*
* @param key The key to be constrained.
* @return {@link Query} object, so you can chain this call.
*
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.notExists("status");
*
*/
public Query notExists(@NotNull String key) {
if (queryValueJSON.isNull(key)) {
if (queryValue.length() > 0) {
queryValue = new JSONObject();
}
queryValue.put(EXISTS, false);
queryValueJSON.put(key, queryValue);
} else if (queryValueJSON.has(key)) {
queryValue.put(EXISTS, false);
queryValueJSON.put(key, queryValue);
}
return this;
}
/**
* Add a constraint that requires a particular reference key details.
*
* @param key key that to be constrained.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.includeReference("for_bug");
*
*/
public Query includeReference(String key) {
if (objectUidForInclude == null) {
objectUidForInclude = new JSONArray();
}
objectUidForInclude.put(key);
return this;
}
/**
* Include tags with which to search entries.
*
* @param tags Comma separated array of tags with which to search entries.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.tags(new String[] { "tag1", "tag2" });
*
*/
public Query tags(@NotNull String[] tags) {
String tagstr = String.join(",", tags);
urlQueries.put("tags", tagstr);
return this;
}
/**
* Sort the results in ascending order with the given key.
Sort the returned entries in ascending order of the
* provided key.
*
* @param key The key to order by.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.ascending("name");
*
*/
public Query ascending(@NotNull String key) {
urlQueries.put("asc", key);
return this;
}
/**
* Sort the results in descending order with the given key.
Sort the returned entries in descending order of
* the provided key.
*
* @param key The key to order by.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.descending("name");
*
*/
public Query descending(@NotNull String key) {
urlQueries.put("desc", key);
return this;
}
/**
* Specifies list of field ids that would be 'excluded' from the response.
*
* @param fieldUid field uid which get 'excluded' from the response.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* ArrayList<String> array = new ArrayList<String>();
* array.add("name");
* array.add("description");
* csQuery.except(array);
*
*/
public Query except(@NotNull List fieldUid) {
if (!fieldUid.isEmpty()) {
if (objectUidForExcept == null) {
objectUidForExcept = new JSONArray();
}
for (String s : fieldUid) {
objectUidForExcept.put(s);
}
}
return this;
}
/**
* Specifies list of field ids that would be 'excluded' from the response.
*
* @param fieldIds field uid which get 'excluded' from the response.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.except(new String[]{"name", "description"});
*
*/
public Query except(@NotNull String[] fieldIds) {
if (fieldIds.length > 0) {
if (objectUidForExcept == null) {
objectUidForExcept = new JSONArray();
}
for (String fieldId : fieldIds) {
objectUidForExcept.put(fieldId);
}
}
return this;
}
/**
* Specifies an array of 'only' keys in BASE object that would be 'included' in the response.
*
* @param fieldUid Array of the 'only' reference keys to be included in response.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.only(new String[]{"name"});
*
*/
public Query only(@NotNull String[] fieldUid) {
if (fieldUid.length > 0) {
if (objectUidForOnly == null) {
objectUidForOnly = new JSONArray();
}
for (String s : fieldUid) {
objectUidForOnly.put(s);
}
}
return this;
}
/**
* Specifies an array of 'only' keys that would be 'included' in the response.
*
* @param fieldUid Array of the 'only' reference keys to be included in response.
* @param referenceFieldUid Key who has reference to some other class object.
* @return {@link Query} object, so you can chain this call.
*
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* ArrayList<String> array = new ArrayList<String>();
* array.add("description");
* array.add("name");
* csQuery.onlyWithReferenceUid(array, "for_bug");
*
*/
public Query onlyWithReferenceUid(@NotNull List fieldUid, @NotNull String referenceFieldUid) {
if (onlyJsonObject == null) {
onlyJsonObject = new JSONObject();
}
JSONArray fieldValueArray = new JSONArray();
for (String s : fieldUid) {
fieldValueArray.put(s);
}
onlyJsonObject.put(referenceFieldUid, fieldValueArray);
if (objectUidForInclude == null) {
objectUidForInclude = new JSONArray();
}
objectUidForInclude.put(referenceFieldUid);
return this;
}
/**
* Specifies an array of 'except' keys that would be 'excluded' in the response.
*
* @param fieldUid Array of the 'except' reference keys to be excluded in response.
* @param referenceFieldUid Key who has reference to some other class object.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* ArrayList<String> array = new ArrayList<String>();
* array.add("description");
* array.add("name");
* csQuery.exceptWithReferenceUid(array, "for_bug");
*
*/
public Query exceptWithReferenceUid(@NotNull List fieldUid, @NotNull String referenceFieldUid) {
if (exceptJsonObject == null) {
exceptJsonObject = new JSONObject();
}
JSONArray fieldValueArray = new JSONArray();
for (String s : fieldUid) {
fieldValueArray.put(s);
}
exceptJsonObject.put(referenceFieldUid, fieldValueArray);
if (objectUidForInclude == null) {
objectUidForInclude = new JSONArray();
}
objectUidForInclude.put(referenceFieldUid);
return this;
}
/**
* Retrieve only count of entries in result.
*
* @return {@link Query} object, so you can chain this call. Note :- Call {@link QueryResult#getCount()}
* method in the success to get count of objects.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.count();
*
*/
public Query count() {
urlQueries.put("count", "true");
return this;
}
/**
* Retrieve count and data of objects in result
*
* @return {@link Query} object, so you can chain this call. Note :- Call {@link QueryResult#getCount()}
* method in the success to get count of objects.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.includeCount();
*
*/
public Query includeCount() {
urlQueries.put("include_count", "true");
return this;
}
/**
* Include Content Type of all returned objects along with objects themselves.
*
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.includeContentType();
*
*/
public Query includeContentType() {
if (urlQueries.has("include_schema")) {
urlQueries.remove("include_schema");
}
urlQueries.put("include_content_type", true);
urlQueries.put("include_global_field_schema", true);
return this;
}
/**
* The number of objects to skip before returning any.
*
* @param number No of objects to skip from returned objects
* @return {@link Query} object, so you can chain this call.
*
* Note: The skip parameter can be used for pagination,
* "skip" specifies the number of objects to skip in the response.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.skip(2);
*
*/
public Query skip(int number) {
urlQueries.put("skip", number);
return this;
}
/**
* A limit on the number of objects to return.
*
* @param number No of objects to limit.
* @return {@link Query} object, so you can chain this call.
*
* Note: The limit parameter can be used for pagination, "
* limit" specifies the number of objects to limit to in the response.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query query = stack.contentType("contentTypeUid").query();
* query.limit(2);
*
*/
public Query limit(int number) {
urlQueries.put(LIMIT, number);
return this;
}
/**
* Add a regular expression constraint for finding string values that match the provided regular expression. This
* may be slow for large data sets.
*
* @param key The key to be constrained.
* @param regex The regular expression pattern to match.
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query query = stack.contentType("contentTypeUid").query();
* query.regex("name", "^browser");
*
*/
public Query regex(@NotNull String key, @NotNull String regex) {
if (queryValueJSON.isNull(key)) {
if (!queryValue.isEmpty()) {
queryValue = new JSONObject();
}
queryValue.put(REGEX, regex);
queryValueJSON.put(key, queryValue);
} else if (queryValueJSON.has(key)) {
queryValue.put(REGEX, regex);
queryValueJSON.put(key, queryValue);
}
return this;
}
/**
* Add a regular expression constraint for finding string values that match the provided regular expression. This
* may be slow for large data sets.
*
* @param key The key to be constrained.
* @param regex The regular expression pattern to match
* @param modifiers Any of the following supported Regular expression modifiers.
*
* use i for case-insensitive matching.
*
*
* use m for making dot match newlines.
*
*
* use x for ignoring whitespace in regex
*
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query query = stack.contentType("contentTypeUid").query();
* query.regex("name", "^browser", "i");
*
*/
public Query regex(@NotNull String key, @NotNull String regex, String modifiers) {
try {
if (queryValueJSON.isNull(key)) {
if (queryValue.length() > 0) {
queryValue = new JSONObject();
}
queryValue.put(REGEX, regex);
if (modifiers != null) {
queryValue.put(OPTIONS, modifiers);
}
queryValueJSON.put(key, queryValue);
} else if (queryValueJSON.has(key)) {
queryValue.put(REGEX, regex);
if (modifiers != null) {
queryValue.put(OPTIONS, modifiers);
}
queryValueJSON.put(key, queryValue);
}
} catch (Exception e) {
throwException(OPTIONS, Constants.QUERY_EXCEPTION, e);
}
return this;
}
/**
* set Language using locale code.
*
* @param locale {@link String} value
* @return {@link Query} object, so you can chain this call
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query query = stack.contentType("contentTypeUid").query();
* query.locale("en-us");
*
*/
public Query locale(@NotNull String locale) {
urlQueries.put("locale", locale);
return this;
}
/**
* This method provides only the entries matching the specified value.
*
* @param value value used to match or compare
* @return {@link Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query query = stack.contentType("contentTypeUid").query();
* query.search("header");
*
*/
public Query search(@NotNull String value) {
if (urlQueries.isNull(value)) {
urlQueries.put("typeahead", value);
}
return this;
}
/**
* Execute a Query and Caches its result (Optional)
*
* @param callback {@link QueryResultsCallBack} object to notify the application when the request has completed.
* @return {@linkplain Query} object, so you can chain this call.
*
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query query = stack.contentType("contentTypeUid").query();
* query.find(new QueryResultsCallBack() {
* @Override
* public void onCompletion(ResponseType responseType, QueryResult queryResult, Error error) {
* }
* });
*
*/
public Query find(QueryResultsCallBack callback) {
Error error;
if (isJsonProper) {
if (!contentTypeUid.isEmpty()) {
execQuery(null, callback);
} else {
throwException("find", Constants.CONTENT_TYPE_NAME, null);
error = new Error();
error.setErrorMessage(errorString);
}
} else {
error = new Error();
error.setErrorMessage(errorString);
}
return this;
}
/**
* Execute a Query and Caches its result (Optional)
*
* @param callBack {@link QueryResultsCallBack} object to notify the application when the request has completed.
* @return {@linkplain Query} object, so you can chain this call.
*
*
*
* Example :
*
*
* Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
* Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.findOne(new QueryResultsCallBack() {
* @Override
* public void onCompletion(ResponseType responseType, ENTRY entry, Error error) {
*
* }
* });
*
*/
public Query findOne(SingleQueryResultCallback callBack) {
if (isJsonProper) {
if (!contentTypeUid.isEmpty()) {
int limit = -1;
if (urlQueries != null && urlQueries.has(LIMIT)) {
limit = (int) urlQueries.get(LIMIT);
}
if (urlQueries != null) {
urlQueries.put(LIMIT, 1);
execQuery(callBack, null);
if (limit != -1) {
urlQueries.put(LIMIT, limit);
}
}
} else {
throwException("find", Constants.CONTENT_TYPE_NAME, null);
}
}
return this;
}
private void throwException(String queryName, String messageString, @Nullable Exception e) {
HashMap errorHashMap = new HashMap<>();
isJsonProper = false;
errorString = messageString;
if (e != null) {
errorHashMap.put(queryName, e.getLocalizedMessage());
}
errorHashMap.put("detail", messageString);
assert e != null;
logger.log(Level.SEVERE, e.getLocalizedMessage(), e);
}
protected void setQueryJson() {
if (queryValueJSON != null && queryValueJSON.length() > 0) {
urlQueries.put(QUERY, queryValueJSON);
}
if (objectUidForExcept != null && objectUidForExcept.length() > 0) {
urlQueries.put("except[BASE][]", objectUidForExcept);
objectUidForExcept = null;
}
if (objectUidForOnly != null && objectUidForOnly.length() > 0) {
urlQueries.put("only[BASE][]", objectUidForOnly);
objectUidForOnly = null;
}
if (onlyJsonObject != null && onlyJsonObject.length() > 0) {
urlQueries.put("only", onlyJsonObject);
onlyJsonObject = null;
}
if (exceptJsonObject != null && exceptJsonObject.length() > 0) {
urlQueries.put(EXCEPT, exceptJsonObject);
exceptJsonObject = null;
}
if (objectUidForInclude != null && objectUidForInclude.length() > 0) {
urlQueries.put("include[]", objectUidForInclude);
objectUidForInclude = null;
}
}
protected void execQuery(SingleQueryResultCallback callBack, QueryResultsCallBack callback) {
String urlString = "content_types/" + contentTypeUid + "/entries";
queryResultCallback = callback;
singleQueryResultCallback = callBack;
setQueryJson();
urlQueries.put(Constants.ENVIRONMENT, this.headers.get(Constants.ENVIRONMENT));
includeLivePreview();
mainJSON.put(QUERY, urlQueries);
fetchFromNetwork(urlString, mainJSON, callback, callBack);
}
private void includeLivePreview() {
Config ci = contentTypeInstance.stackInstance.config;
if (ci.enableLivePreview
&& ci.livePreviewContentType.equalsIgnoreCase(contentTypeUid)
&& (ci.livePreviewHash == null
|| ci.livePreviewHash.isEmpty())) {
ci.livePreviewHash = "init";
}
}
// fetch from network.
private void fetchFromNetwork(String urlString, JSONObject jsonMain, ResultCallBack callback, SingleQueryResultCallback resultCallback) {
LinkedHashMap urlParams = getUrlParams(jsonMain);
if (resultCallback != null) {
new CSBackgroundTask(this, contentTypeInstance.stackInstance, Constants.SINGLEQUERYOBJECT, urlString,
this.headers, urlParams, Constants.REQUEST_CONTROLLER.QUERY.toString(), resultCallback);
} else {
new CSBackgroundTask(this, contentTypeInstance.stackInstance, Constants.QUERYOBJECT, urlString,
this.headers, urlParams, Constants.REQUEST_CONTROLLER.QUERY.toString(), callback);
}
}
private LinkedHashMap getUrlParams(JSONObject jsonMain) {
LinkedHashMap hashMap = new LinkedHashMap<>();
JSONObject queryJSON = jsonMain.optJSONObject(QUERY);
if (queryJSON != null && queryJSON.length() > 0) {
Iterator itr = queryJSON.keys();
while (itr.hasNext()) {
String key = itr.next();
Object value = queryJSON.opt(key);
hashMap.put(key, value);
}
}
return hashMap;
}
@Override
public void getResult(Object object, String controller) {
// It would not be called.
//System.out.println(object);
}
@Override
public void getResultObject(List