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 ; } 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 ( ")" ) ; 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 [ ] { } ) ; } if ( ! includeTableFieldsParam ) { return returnVal ; } if ( returnVal == null ) { return returnVal ; } 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