All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.contentstack.sdk.Query Maven / Gradle / Ivy

There is a newer version: 2.0.1
Show newest version
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 objects, JSONObject jsonObject, boolean isSingleEntry) { List objectList = new ArrayList<>(); for (Object object : objects) { Entry entry; try { entry = contentTypeInstance.stackInstance.contentType(contentTypeUid) .entry(((EntryModel) object).uid); } catch (Exception e) { entry = new Entry(contentTypeUid); } entry.setUid(((EntryModel) object).uid); entry.resultJson = ((EntryModel) object).jsonObject; entry.title = ((EntryModel) object).title; entry.url = ((EntryModel) object).url; entry.setTags(((EntryModel) object).tags); objectList.add(entry); } if (isSingleEntry) { Entry entry = contentTypeInstance.entry(); if (!objectList.isEmpty()) { entry = objectList.get(0); } if (singleQueryResultCallback != null) { singleQueryResultCallback.onRequestFinish(ResponseType.NETWORK, entry); } } else { QueryResult queryResultObject = new QueryResult(); queryResultObject.setJSON(jsonObject, objectList); if (queryResultCallback != null) { queryResultCallback.onRequestFinish(ResponseType.NETWORK, queryResultObject); } } } /** * This method adds key and value to an Entry. Parameters: * * @param key: The key as string which needs to be added to the Query * @param value: The value as string which needs to be added to the Query * @return - Query * *
*
* Example :
* *
     *         Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
     *         Query csQuery = stack.contentType("contentTypeUid").query();
     *         csQuery.addParam("key", "some_value");
     *         csQuery.findOne(new QueryResultsCallBack() {
     *             @Override
     *             public void onCompletion(ResponseType responseType, ENTRY entry, Error error) {
     *             }
     *         });
     *         
*/ public Query addParam(@NotNull String key, @NotNull String value) { urlQueries.put(key, value); return this; } /** * This method also includes the content type UIDs of the referenced entries returned in the response * * @return {@link Query}
* *
*
* Example :
* *
     *          Stack stack = Contentstack.stack( "apiKey", "deliveryToken", "environment");
     *          Query csQuery = stack.contentType("contentTypeUid").query();
* csQuery.includeReferenceContentTypUid(); * csQuery.findOne(new QueryResultsCallBack() {
* @Override * public void onCompletion(ResponseType responseType, ENTRY entry, Error error) {
* } * });
*
*/ public Query includeReferenceContentTypUid() { urlQueries.put("include_reference_content_type_uid", "true"); return this; } /** * Get entries having values based on referenced fields. This query retrieves all entries that satisfy the query * conditions made on referenced fields. * * @param key The key to be constrained * @param queryObject {@link Query} object, so you can chain this call * @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.whereIn("due_date", csQuery);
     *         
*/ public Query whereIn(@NotNull String key, Query queryObject) { JSONObject inQueryObj = new JSONObject(); inQueryObj.put("$in_query", queryObject.queryValueJSON.toString()); queryValueJSON.put(key, inQueryObj); return this; } /** * Get entries having values based on referenced fields. This query works the opposite of $in_query and retrieves * all entries that does not satisfy query conditions made on referenced fields. * * @param key The key to be constrained * @param queryObject {@link Query} object, so you can chain this call * @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.whereNotIn("due_date", csQuery);
     *         
*/ public Query whereNotIn(@NotNull String key, Query queryObject) { JSONObject inQueryObj = new JSONObject(); inQueryObj.put("$nin_query", queryObject.queryValueJSON.toString()); queryValueJSON.put(key, inQueryObj); return this; } /** * Retrieve the published content of the fallback locale if an entry is not localized in specified locale * * @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.includeFallback();
     *         
*/ public Query includeFallback() { urlQueries.put("include_fallback", true); return this; } /** * @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.includeEmbeddedObjects()
     *         
*/ public Query includeEmbeddedItems() { urlQueries.put("include_embedded_items[]", "BASE"); return this; } /** * Includes Branch in the entry response * * @return {@link Query} object, so you can chain this call.
* *
*
* Example :
* *
     *         Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
     *         Query query = stack.contentType("contentTypeUid").query();
     *         entry.includeBranch();
     *         
*/ public Query includeBranch() { urlQueries.put("include_branch", true); return this; } /** * Includes Metadata in the entry response * * @return {@link Query} object, so you can chain this call.
* *
*
* Example :
* *
     *         Stack stack = Contentstack.stack("apiKey", "deliveryToken", "environment");
     *         Query query = stack.contentType("contentTypeUid").query();
     *         entry.includeMetadata();
     *         
*/ public Query includeMetadata() { urlQueries.put("include_metadata", true); return this; } }