fluid-api/src/main/java/com/fluidbpm/program/api/util/elasticsearch/ESFormUtil.java
public List<Form> getFormDescendants(
			List<Long> electronicFormIdsParam,
			boolean includeFieldDataParam,
			boolean includeTableFieldsParam,
			boolean includeTableFieldFormRecordInfoParam)
	{
		if(electronicFormIdsParam == null ||
				electronicFormIdsParam.isEmpty())
		{
			return null;
		}

		//String stringQuery = "formType:(\"JIT Schedule\" \"SMT Training\") AND flowState:\"Not In Flow\"";

		//Query using the descendantId directly...
		StringBuffer descendantQuery = new StringBuffer(Form.JSONMapping.ANCESTOR_ID);
		descendantQuery.append(":(");

		for(Long electronicFormId : electronicFormIdsParam)
		{
			descendantQuery.append("\"");
			descendantQuery.append(electronicFormId);
			descendantQuery.append("\"");
			descendantQuery.append(" ");
		}

		String fullQueryToExec = descendantQuery.toString();
		fullQueryToExec = fullQueryToExec.substring(
				0, fullQueryToExec.length() - 1);
		fullQueryToExec = fullQueryToExec.concat(")");

		//Search for the Descendants...
		List<Form> returnVal = null;
		if(includeFieldDataParam)
		{
			returnVal = this.searchAndConvertHitsToFormWithAllFields(
					QueryBuilders.queryStringQuery(fullQueryToExec),
					Index.DOCUMENT,
					DEFAULT_OFFSET, MAX_NUMBER_OF_TABLE_RECORDS,
					new Long[]{});
		}
		else
		{
			returnVal = this.searchAndConvertHitsToFormWithNoFields(
					QueryBuilders.queryStringQuery(fullQueryToExec),
					Index.DOCUMENT,
					DEFAULT_OFFSET, MAX_NUMBER_OF_TABLE_RECORDS,
					new Long[]{});
		}

		//Whether table field data should be included...
		if(!includeTableFieldsParam)
		{
			return returnVal;
		}

		//No result...
		if(returnVal == null)
		{
			return returnVal;
		}

		//Populate in order to have table field data...
		for(Form descendantForm : returnVal)
		{
			this.populateTableFields(
					false,
					includeFieldDataParam,
					descendantForm.getFormFields());
		}

		return returnVal;
	}
public List<Form> getFormDescendants(
			List<Long> electronicFormIdsParam,
			boolean includeFieldDataParam,
			boolean includeTableFieldsParam,
			boolean includeTableFieldFormRecordInfoParam)
	{
		if(electronicFormIdsParam == null ||
				electronicFormIdsParam.isEmpty())
		{
			return null;
		}

		//String stringQuery = "formType:(\"JIT Schedule\" \"SMT Training\") AND flowState:\"Not In Flow\"";

		//Query using the descendantId directly...
		StringBuffer descendantQuery = new StringBuffer(Form.JSONMapping.ANCESTOR_ID);
		descendantQuery.append(":(");

		for(Long electronicFormId : electronicFormIdsParam)
		{
			descendantQuery.append("\"");
			descendantQuery.append(electronicFormId);
			descendantQuery.append("\"");
			descendantQuery.append(" ");
		}

		String fullQueryToExec = descendantQuery.toString();
		fullQueryToExec = fullQueryToExec.substring(
				0, fullQueryToExec.length() - 1);
		fullQueryToExec = fullQueryToExec.concat(")");

		//Search for the Descendants...
		List<Form> returnVal = null;
		if(includeFieldDataParam)
		{
			returnVal = this.searchAndConvertHitsToFormWithAllFields(
					QueryBuilders.queryStringQuery(fullQueryToExec),
					Index.DOCUMENT,
					DEFAULT_OFFSET, MAX_NUMBER_OF_TABLE_RECORDS,
					new Long[]{});
		}
		else
		{
			returnVal = this.searchAndConvertHitsToFormWithNoFields(
					QueryBuilders.queryStringQuery(fullQueryToExec),
					Index.DOCUMENT,
					DEFAULT_OFFSET, MAX_NUMBER_OF_TABLE_RECORDS,
					new Long[]{});
		}

		//Whether table field data should be included...
		if(!includeTableFieldsParam)
		{
			return returnVal;
		}

		//No result...
		if(returnVal == null)
		{
			return returnVal;
		}

		//Populate in order to have table field data...
		for(Form descendantForm : returnVal)
		{
			this.populateTableFields(
					false,
					includeFieldDataParam,
					descendantForm.getFormFields());
		}

		return returnVal;
	}
Gets the descendants for the {@code electronicFormIdsParam} Forms.

@param electronicFormIdsParam Identifiers for the Forms to retrieve.
@param includeFieldDataParam Whether to populate the return {@code List<Form>} fields.
@param includeTableFieldsParam Whether to populate the return {@code List<Form>} table fields.
@param includeTableFieldFormRecordInfoParam Does table record form data need to be included.

@return {@code List<Form>} descendants.

@see Form