Class DSRequest

java.lang.Object
com.isomorphic.base.Base
com.isomorphic.rpc.BaseRequest<DSRequest,DSResponse>
com.isomorphic.datasource.DSRequest
All Implemented Interfaces:
com.isomorphic.base.IAutoConfigurable, com.isomorphic.datasource.Committable, Callable<DSResponse>

public class DSRequest extends BaseRequest<DSRequest,DSResponse> implements com.isomorphic.datasource.Committable, Callable<DSResponse>
Server-side representation of a DataSource request initiated by a client-side DataBoundComponent or programmatically by custom client-side JavaScript.

When databound components need to load or persist data, they make Ajax background requests to the server. Those requests are decoded into DSRequest Java objects by SmartClient's server-side Java libraries.

You obtain a DSRequest by either:

  • using the DMI system (Direct Method Invocation) simply declaring a DSRequest as a parameter of a method that will be invoked via DMI (see DMI topic in client-side reference).
  • implementing a Custom DataSource (see QuickStart Guide) and implementing the DataSource.execute() method
  • creating an RPCManager (generally in a servlet) and calling RPCManager.getDSRequest() or RPCManager.getRequests().

DSRequests can also be used entirely server-side. Your server-side Java code can create a DSRequest via "new DSRequest()" at any time, and call execute() on it in order to perform operations against DataSources. These requests are processed by SmartClient Server exactly as if they had come from the client.

If you are integrating SmartClient with a pre-existing Java data store, you can call various getters on the DSRequest, such as getCriteria(), to retrieve request parameters that you can then use with your pre-existing data store. For example, when working with an ORM (Object Relational Mapping) system, a typical way of processing an "update" DSRequest is to:

  1. use DSRequest.getCriteria() to retrieve the primary key for the object being updated, and fetch that object from your ORM system
  2. use DSRequest.getValues() in combination with DataTools.setProperties() to apply new properties to the object, based on the Java Beans naming convention
  3. store the modified object using your ORM system

See the QuickStart Guide for further details on all of the above approaches, and the server request processing lifecycle.

Built-in connectors: SQL, Hibernate and JPA

The SmartClient Server can also automatically process DSRequests from DataSources with serverType="sql", "hibernate" or "jpa". In this case, you can call DSRequest.execute() to cause the default behavior to occur, which will return a DSResponse populated with data supplied by JPA, Hibernate or SQL.

By modifying the DSRequest before you call execute() and by modifying the DSResponse you receive, you can combine SmartClient's built-in persistence engine support with custom processing.

For example, if you have a SQL table of records that are specific to each user, and there is a column containing the user's id, you could use setFieldValue(java.lang.Object, java.lang.Object) to ensure the DSRequest always contains the user's id. This would ensure that fetch, add, update and remove operations are always restricted to the user's own data.

See the QuickStart Guide for further details on modifying DSRequests and DSResponses to add custom behavior when using the built-in connectors.

See Also:
  • Field Details

    • ENDROW_UNSET

      public static final long ENDROW_UNSET
      If endRow is set to this constant, then there is no set bound for the number of records the server should return for the current request.
      See Also:
  • Constructor Details

    • DSRequest

      public DSRequest(String dataSourceName, String operationType, ValidationContext vc)
      Creates an empty DSRequest bound to the named datasource with the specified operationType. Depending on the operation you're performing you'll need to call some other setters on the returned instance before calling execute().
      Parameters:
      dataSourceName - name of the datasource for this request
      operationType - operationType for this request
      vc - the ValidationContext to initialize this request with
    • DSRequest

      public DSRequest(String dataSourceName, String operationType, RPCManager rpcManager)
      Creates an empty DSRequest bound to the named datasource with the specified operationType, and associated with the specified RPCManager. Depending on the operation you're performing you'll need to call some other setters on the returned instance before calling execute().
      Parameters:
      dataSourceName - name of the datasource for this request
      operationType - operationType for this request
      rpcManager - The RPCManager in use for this request
    • DSRequest

      public DSRequest(String dataSourceName, String operationType, com.isomorphic.datasource.DSCacheManager dsCacheManager)
      Creates an empty DSRequest bound to the named datasource with the specified operationType, and associated with the specified DSCacheManager. This constructor is preferred to calling setDSCacheManager() after DSRequest creation, because the DS cache is useful during DSRequest construction

      Depending on the operation you're performing you'll need to call some other setters on the returned instance before calling execute().

      Parameters:
      dataSourceName - name of the datasource for this request
      operationType - operationType for this request
      dsCacheManager - The DSCacheManager in use for this request
  • Method Details

    • getValidated

      public boolean getValidated()
      Returns true if this DSRequest has been validated. Ordinarily, this means the DSRequest's validate() method has been called and did not return any errors, but see also setValidated(boolean).
      Returns:
      true if this DSRequest has been validated
    • setValidated

      public DSRequest setValidated(boolean newValue)
      Sets the validated state of this DSRequest. Ordinarily, a DSRequest is considered validated if its validate() method has been called and did not return any errors. You can use this API to directly set the validated state of a DSRequest.
      • If you set the validated state to true, and normal SmartClient/SmartGWT Server validation has not already been run, it will be skipped. You would do this if you had some reason for wanting to prevent ordinary validation
      • If you set the validated state to false, it is possible that normal SmartClient/SmartGWT Server validation will run again. For example, a DSRequest that is passed to a DMI goes through ordinary validation before the DMI is called. If the DMI calls setValidated(false) on the DSREquest then executes it, it will be validated again. This may be desirable if the DMI alters the DSRequest in some way/
      Parameters:
      newValue - whether this request has been validated
      Returns:
      the DSRequest itself
    • setPartOfTransaction

      public DSRequest setPartOfTransaction(boolean newValue)
      Controls how success or failure is reported for a request that executes alongside an automatically handled transaction.

      If you setPartOfTransaction(true) and the automatically handled transaction fails, the status for your DSRequest will be reported as STATUS_TRANSACTION_FAILED, which is an indication to the client that the DSRequest did nothing.

      Use this API if you have written custom Java code to handle a DSRequest, and:

      • you use @link{DataSource.getTransactionObject(DSRequest,String,String)} to obtain the current transaction and use hand-written JDBC, JPA or Hibernate code to run updates in the scope of the current transaction. Calling setPartOfTransaction(true) in this case reflects the fact that your updates will be automatically rolled back along with other updates in the automatically managed transaction.
      • you add use @link{RPCManager.registerCallback()} to be notified when the automatically managed transaction fails, and you manually rollback the consequences of your logic (for example, you remove a new file that had been added)
      You can also use this API to obtain correct behavior in the case of Exceptions from your own DMI code. For example, say you have this DMI method:
         public DSResponse myDMI(DSRequest req) {
             String str = req.getFieldValue("someField").toLowerCase();
             // Do something with str here
             return req.execute();
         }
       
      Here, by blindly calling a method without first checking for null, you introduce the possibility of this DMI crashing before the execute() call; the execute() call would have determined that this DSRequest should be part of the automatic transaction, meaning a failure of it would have rolled back the whole transaction. This early failure in DMI code leaves the DSRequest still separate from the transaction, so rollback would not happen.

      What we do in a case like this is check if the DSRequest would have joined the automatic transaction if the DMI had been bypassed: if it would, the DSRequest is considered to be part of the transaction. So in this case, the overall transaction would be rolled back in the event of a NullPointerException arising from the first line of the DMI method. That is correct and desirable failure behavior for this case and the majority of ordinary DMI usages on a built-in DataSource type, where the DMI is there to augment the built-in functionality, and dsRequest.execute() will ultimately be called.

      However, a DMI can do anything at all - there is no certainty that dsRequest.execute() will eventually be called. If the DMI described above did not make that call then the request would not have been part of the transaction regardless of success or failure, and our heuristic test - would the request have joined the transaction if the DMI had been bypassed? - would make the wrong decision. To prevent the possibility of this happening, you would either:

      • Call setPartOfTransaction(false) right at the top of your DMI method. This would handle transactional failure correctly without any further code to write
      • Put the entire DMI method inside a try-catch block and manually rollback the transaction if any Exception is thrown. You would only do this if you had a specific reason - it is easier to let the framework handle the transaction lifecycle. The method of committing or rolling back varies by DataSource type. For example, if it were a SQLDataSource, you would manually rollback like this:
                 SQLTransaction.rollbackTransaction(dsRequest.getRPCManager());
                 
      Parameters:
      newValue - whether this request is part of a transaction
      Returns:
      the DSRequest
      See Also:
    • getTextMatchStyle

      public String getTextMatchStyle()
      Returns the textMatchStyle in force for this DSRequest, or null if none is set. See the client-side documentation for details of TextMatchStyle.
      Returns:
      The textMatchStyle in force for this DSRequest
    • setTextMatchStyle

      public DSRequest setTextMatchStyle(String textMatchStyle)
      Sets the textMatchStyle in force for this DSRequest. See the client-side documentation for details of TextMatchStyle.
      Parameters:
      textMatchStyle - the text match style to set
      Returns:
      the DSRequest
    • getRequestContext

      @Deprecated public RequestContext getRequestContext()
      Deprecated.
      Please use BaseRequest.getContext() instead.
      Returns:
      the RequestContext for this request
    • getOperationType

      public String getOperationType()
      Returns the type of this DataSource operation.
      Returns:
      One of: "fetch", "add", "remove", "update", "validate" or "custom".
    • setOperationType

      public DSRequest setOperationType(String operationType)
      Sets the operation type. Valid values are one of: "fetch", "add", "remove", "update" or "custom".
      Parameters:
      operationType - the operation type - see above for valid values.
      Returns:
      the DSRequest
    • getOperationId

      public String getOperationId()
      Optional operationId passed by the client.

      The operationId is a means for client-side DataBound Components to request variants of the basic DataSource operations that the server may support, such as normal fetch operations vs fetch operations that use a single parameter and do full-text search. See the Client Reference for DSRequest.operationId for more information.

      Returns:
      the operationId
    • setOperationId

      public DSRequest setOperationId(String operationId)
      For server-initiated DSRequests, sets the operationId to control which operationBinding is used when fulfilling the requests.
      Parameters:
      operationId - the operationId to use
      Returns:
      the DSRequest
      See Also:
    • getComponentId

      public String getComponentId()
      Optional componentId passed by the client.

      For requests submitted by a SmartClient DataBoundComponent, this is the component ID.

      Returns:
      the componentId
    • getCriteria

      public Map getCriteria()
      Returns the criteria for this operation as a set of key-value pairs where the keys are field names and the values are field values. The meaning of criteria varies by operationType.

      If the operationType is "fetch", then the criteria specifies the search criteria.

      If the operationType is "remove" or "update" then the criteria are the primary key/value pairs for the record to be updated or deleted. This set of fields is derived directly from the field specification in the dataSource for this operation - all fields marked as {primaryKey: true} are considered primary keys and their field names and values will be sent as part of the criteria in this case.

      The criteria returned from this method are in simple Java Collections form (as they are sent over the network). Use getAdvancedCriteria() to retrieve an AdvancedCriteria which provides simple APIs for manipulating criteria. The modified criteria can be applied to the DSRequest via setAdvancedCriteria(com.isomorphic.criteria.AdvancedCriteria).

      Returns:
      the criteria for this DSRequest
      See Also:
    • getAdvancedCriteria

      public AdvancedCriteria getAdvancedCriteria()
      Returns the advanced criteria for this operation.

      If criteria were passed as simple Criteria this method will convert them to the more general AdvancedCriteria format by turning them into an AND Criterion containing one or more "startWith" or "contains" Criteria according to dsRequest.textMatchStyle.

      Note that AdvancedCriteria will only be able to be executed by the built-in server DataSources (JPA, Hibernate, SQL) in Power Edition and above.

      Returns:
      the advanced criteria for this DSRequest
    • getIsAdvancedCriteria

      public boolean getIsAdvancedCriteria()
      Check if current criteria is advanced.

      AdvancedCriteria has "_constructor" parameter set to "AdvancedCriteria".

      Returns:
      flag showing if current criteria is advanced.
    • setAdvancedCriteria

      public DSRequest setAdvancedCriteria(AdvancedCriteria advancedCriteria)
      Sets the criteria for this request to the provided AdvancedCriteria.

      Note: AdvancedCriteria will only be able to be executed by the built-in server DataSources (JPA, Hibernate, SQL) in Power Edition and above.

      Parameters:
      advancedCriteria - the criteria to use for this DSRequest
      Returns:
      the DSRequest
      See Also:
    • getClientSuppliedCriteria

      public Map getClientSuppliedCriteria()
      Returns the criteria submitted by the client for this operation as a set of key-value pairs where the keys are field names and the values are field values. There may be differences between this set of values and the set returned by getCriteria(), because declarative security settings or custom server logic may have affected the latter. This method is provided so that your code can determine what the client actually sent, regardless of any server processing that has taken place.
      Returns:
      the criteria for this DSRequest
      See Also:
    • getCriteriaSets

      public List getCriteriaSets()
      Returns the criteria in the request as a List, even if singular.

      Custom client-side code for submitting "update"s or "remove"s can pass multiple sets of criteria and values and oldValues as an alternative to using queuing (see the client-side API RPCManager.startQueue()). If you take this approach, calling getOldValueSets() is a convenience method for always retrieving sets of values as a List.

      Returns:
      List of criteria sets for this request
      See Also:
    • setCriteria

      public DSRequest setCriteria(Object criteria)
      Sets the criteria for this DSRequest. You may pass either a Map or a List of Maps, but note that criteria has slightly different meanings for different operations, so be sure to read the API for getCriteriaSets() on this method for a description of what's required.

      The criteria passed in this method are in simple Java Collections form (as they are sent over the network), but you can get use setAdvancedCriteria(AdvancedCriteria) with AdvancedCriteria helper classes: AdvancedCriteria exists to assist in modifying the criteria.

      If AdvancedCriteria passed to this method setAdvancedCriteria(AdvancedCriteria) method will be used.

      Parameters:
      criteria - Map or List of Maps: the criteria to use for this DSRequest
      Returns:
      the DSRequest
      See Also:
    • setCriteria

      public DSRequest setCriteria(String fieldName, Object value)
      Sets the criteria for this DSRequest. This is a convenience method for the common case when you only have a single criterion.
      Parameters:
      fieldName - The field name
      value - The criterion value
      Returns:
      the DSRequest
      See Also:
    • clearUploadedFiles

      public DSRequest clearUploadedFiles()
      Clears any uploaded files from this DSRequest. You may wish to do this in the case where you have a DMI method that has already dealt with uploaded files and you wish to prevent any downstream processing from attempting to do so again. Note that you should not actually need to manually clear uploaded files, if your DataSource is correctly configured.
      Returns:
      the DSRequest
    • getUploadedFile

      public ISCFileItem getUploadedFile(String fieldName) throws Exception
      Parameters:
      fieldName - Form field of type 'binary'.
      Returns:
      ISCFileItem containing uploaded file for specified field, or null if no file was uploaded for the specified field.
      Throws:
      Exception - if an error occurs while retrieving the uploaded file
    • getUploadedFiles

      public List getUploadedFiles()
      Returns:
      The list of ISCFileItems representing uploaded files on this DSRequest.
    • getUploadedFileStream

      public InputStream getUploadedFileStream(String fieldName) throws Exception
      Parameters:
      fieldName - Form field of type 'binary'.
      Returns:
      InputStream representing uploaded file for specified field, or null if no file was uploaded for the specified field. Note that this InputStream is not necessarily the same one encapsulated by the corresponding ISCFileItem. Please see the ISCFileItem documentation for details
      Throws:
      Exception - if an error occurs while retrieving the uploaded file stream
      See Also:
    • getUploadedFileStreams

      public List getUploadedFileStreams()
      Returns:
      The list of InputStreams representing uploaded files on this DSRequest. Note that these InputStreams are not necessarily the same ones encapsulated by the ISCFileItem objects they pertain to. Please see the ISCFileItem documentation for details
      See Also:
    • setIncludeBinaryFields

      public void setIncludeBinaryFields(boolean includeBinaryFields)
      Allows to override default binary fields behavior for server-initiated DSRequests that target SQLDataSource.

      By default binary fields are:

      • not selected if request came from the client and it is not a download request
      • not selected if it is an automatic cache sync request
      • selected if it is server-initiated request
      Parameters:
      includeBinaryFields - false to skip selecting binary fields
    • getIncludeBinaryFields

      public boolean getIncludeBinaryFields()
      Returns:
      whether binary fields should be included in the response
      See Also:
    • getValues

      public Map getValues()
      Returns the values for this operation as a set of key-value pairs where the keys are field names and the values are field values. The meaning of values varies by operationType.

      If the operationType is "add" then the values are interpreted as a complete record to add. Note that a complete record at this stage may be missing primary keys that are expected to be auto-generated by the persistence layer.

      If the operationType is "update", then the values represent the new values for the records matching the criteria specified on this request.

      As a convenience, this method returns the criteria if this DSRequest is of type fetch or remove.

      Returns:
      the values for this DSRequest
      See Also:
    • getClientSuppliedValues

      public Map getClientSuppliedValues()
      Returns the values that the client submitted for this operation as a set of key-value pairs where the keys are field names and the values are field values. There may be differences between this set of values and the set returned by getValues(), because declarative security settings or custom server logic may have affected the latter. This method is provided so that your code can determine what the client actually sent, regardless of any server processing that has taken place.

      As a convenience, this method returns the criteria that the client submitted if this DSRequest is of type fetch or remove.

      Returns:
      the values that the client actually sent for this DSRequest
      See Also:
    • getValueSets

      public List getValueSets()
      Returns the values in the request as a List, even if singular.

      Custom client-side code for submitting "update"s or "remove"s can pass multiple sets of criteria and values and oldValues as an alternative to using queuing (see the client-side API RPCManager.startQueue()). If you take this approach, calling getOldValueSets() is a convenience method for always retrieving sets of values as a List.

      Returns:
      List of value sets for this request.
      See Also:
    • setValues

      public DSRequest setValues(Object values)
      Sets the values for this DSRequest. You may pass either a Map or a List of Maps. The List type is typically used for a DataSource.OP_ADD operation with multiple records.
      Parameters:
      values - Map or List of Maps - the values to use for this DSRequest
      Returns:
      the DSRequest
    • getOldValues

      public Map getOldValues()
      For an "update" or "remove" operation, returns the complete original record as it was delivered to the client, as a set of key-value pairs where the keys are field names and the values are field values.

      The server can compare the oldValues to the most recent stored values in order to detect that the user was looking at stale values when the user submitted changes (NOTE: this means of detecting concurrent edit is sometimes called "long transactions").

      Note that client logic must be written to pass oldValues. SmartClient DataBound Components do so automatically, but manually submitted DSRequests may not.

      Returns:
      the oldValues for this DSRequest
      See Also:
    • getOldValueSets

      public List getOldValueSets()
      Returns the oldValues in the request as a List, even if singular.

      Custom client-side code for submitting "update"s or "remove"s can pass multiple sets of criteria and values and oldValues as an alternative to using queuing (see the client-side API RPCManager.startQueue()). If you take this approach, calling getOldValueSets() is a convenience method for always retrieving sets of values as a List.

      Returns:
      List of value sets for this request.
      See Also:
    • setOldValues

      public DSRequest setOldValues(Map oldValues)
      Sets the "old values" for this DSRequest (ie, the values as they were before the set of changes represented by this request).
      Parameters:
      oldValues - Map - the old values to use for this DSRequest
      Returns:
      the DSRequest
    • getSortBy

      public String getSortBy()
      This is a convenience method to be used when you know only a single sortBy field has been specified. Please see the getSortByFields() method on this class for a description of how ascending/descending sort is encoded.

      If you call this method on a DSRequest that has multiple sortBy fields specified, a warning will be logged and the first sortBy field will be returned.

      Returns:
      name of field to sort by
      See Also:
    • getSortByFields

      public List getSortByFields()
      The sortBy specification is only valid for the fetch operation since it specifies the sort order for the returned data.

      This method signature is the generic method that returns all fields for which a sort has been requested. If the list contains more than one entry, then that means the data should be sorted by the first field in the list, then within that first sort data should be sorted by the next field in the list and so on. So the second sortBy field can only affect data that has the same value for the first sortBy field.

      The returned value is a List of Strings that are the names of the fields to sort by. If the String is prefixed by a - then that specifies descending order. Otherwise it's a request for an ascending sort on that field.

      A concrete example of when a sortBy is sent by an ISC databound component: Let's say you have a ListGrid that has a partially loaded dataset (the dataset is too large to be on the client at once, so you're only showing, say, the first 100 rows). If you now click on one of the columns to sort by that column, the ListGrid will send a DSRequest to the server with a sortBy fieldName of the field that was clicked on. Since not all data is present on the client, the grid can't do the sort client-side (and still continue to display the first 100 matches to the current filter criteria).

      Returns:
      set of fields to sort by
    • setSortBy

      public DSRequest setSortBy(Object sortBy)
      Sets the field or fields to sort by.
      Parameters:
      sortBy - String or List of Strings: field or list of fields to sort by. Note that a prefix of - can be used to specify descending order sort.
      Returns:
      the DSRequest
      See Also:
    • getGroupBy

      public List<String> getGroupBy()
      List of fields to group results by.

      Valid only for an operation of type "fetch". See the Server Summaries overview in the client-side documentation for details and examples of usage.

      NOTE: this feature is supported only in Power Edition or above, and only when using the built-in SQL, JPA or Hibernate connectors.

      Returns:
      List with field names to group by, or null if no grouping is configured
      See Also:
    • setGroupBy

      public DSRequest setGroupBy(List<String> groupBy)
      List of fields to group results by.

      Valid only for an operation of type "fetch". See the Server Summaries overview in the client-side documentation for details and examples of usage.

      NOTE: this feature is supported only in Power Edition or above, and only when using the built-in SQL, JPA or Hibernate connectors.

      Parameters:
      groupBy - List with field names to group by.
      Returns:
      this DSRequest for method chaining
      See Also:
    • setGroupBy

      public DSRequest setGroupBy(String... groupBy)
      For fetch operation group by fields can be set. In this case only fields that appear in this List and in dsRequest.summaryFunctions attribute will be fetched.
      Parameters:
      groupBy - String... with field names to group by.
      Returns:
      this DSRequest for method chaining
      See Also:
    • getSummaryFunctions

      public Map<String,SummaryFunctionType> getSummaryFunctions()
      A mapping from field names to summary functions to be applied to each field.

      Valid only for an operation of type "fetch". See the Server Summaries overview in the client-side documentation for details and examples of usage.

      NOTE: this feature is supported only in Power Edition or above, and only when using the built-in SQL, JPA or Hibernate connectors.

      If you need to get all summary functions requested by the client, even if they are not framework built-ins, see getRawSummaryFunctions().

      Returns:
      Map<String,SummaryFunctionType> with field names as keys and summary functions as values.
      See Also:
    • setSummaryFunctions

      public DSRequest setSummaryFunctions(Map<String,SummaryFunctionType> summaryFunctions)
      A mapping from field names to summary functions to be applied to each field.

      Valid only for an operation of type "fetch". See the Server Summaries overview in the client-side documentation for details and examples of usage.

      NOTE: this feature is supported only in Power Edition or above, and only when using the built-in SQL, JPA or Hibernate connectors.

      Parameters:
      summaryFunctions - Map<String,SummaryFunctionType> with field names as keys and summary functions as values.
      Returns:
      this DSRequest for method chaining
      See Also:
    • getRawSummaryFunctions

      public Map<String,String> getRawSummaryFunctions()
      Allows you to retrieve all summary functions requested by the client, even if they are not framework built-ins.

      getSummaryFunctions() will only return recognized, built-in summaryFunctions from the SummaryFunctionType enum, so getRawSummaryFunctions() is the only way to retrieve client-requested summary functions that are not built into the framework, so that you can perform custom aggregation. See the Server Summaries > Custom Aggregation example in the Showcase.

      NOTE: this feature is supported only in Power Edition or above, and only when using the built-in SQL, JPA or Hibernate connectors.

      Returns:
      Map<String,String> with field names as keys and summary functions as values.
      See Also:
    • setRawSummaryFunctions

      public DSRequest setRawSummaryFunctions(Map<String,String> rawSummaryFunctions)
      Allows you to set all summary functions requested by the client, even if they are not framework built-ins.

      getSummaryFunctions() will only return recognized, built-in summaryFunctions from the SummaryFunctionType enum, so getRawSummaryFunctions() is the only way to retrieve client-requested summary functions that are not built into the framework, so that you can perform custom aggregation. See the Server Summaries > Custom Aggregation example in the Showcase.

      NOTE: this feature is supported only in Power Edition or above, and only when using the built-in SQL, JPA or Hibernate connectors.

      Parameters:
      rawSummaryFunctions - Map<String,SummaryFunctionType> with field names as keys and summary functions as values.
      Returns:
      this DSRequest for method chaining
      See Also:
    • isPaged

      public boolean isPaged()
      Returns true if the current request has is requesting partial set of data using startRow/endRow parameters. Specifically, this method returns true if startRow is non-zero or endRow has a value other than DSRequest.ENDROW_UNSET.
      Returns:
      true if the request is for a paged data set
      See Also:
    • setBatchSize

      public DSRequest setBatchSize(long batchSize)
      If a batch size has been set it will be passed as a hint to the JDBC API using ResultSet.setFetchSize() and Statement.setFetchSize().

      The batch size will normally be based on endRow if that has been set and batchSize will then be set to the number of rows to be returned, so they are all fetched at once.

      For a request which does not have endRow set you can call setBatchSize(long) to try and influence the JDBC driver as a performance optimization. When using a Hibernate datasource criteria.setFetchSize will be called with this value.

      The batch size can also be controlled from a config property through server.properties, namely, 'sql.defaultFetchBatchSize'. By default this property is unset but once set it configures the batchSize for any "fetch" dsRequest that does not have an endRow and has not had setBatchSize() called explicitly If you use setBatchSize() to set a negative batch size, SmartClient Server will not call the JDBC setFetchSize() API at all, so you will get the default behavior of the JDBC driver / database.

      Parameters:
      batchSize - the size of the batch as a whole number.
      Returns:
      this DSRequest, allowing for chaining of method calls.
      See Also:
    • getStartRow

      public long getStartRow()
      When components that are capable or showing multiple records at once are bound to datasources with large datasets, it becomes important to only send those records that are currently visible in the component (or can become visible with a typical user action).

      When multi-record capable components make requests to the server for data, they send the startRow and endRow parameters to indicate the slice of data they need to show to the user right now.

      You can use the isPaged() method on this request to check if you need to respect startRow/endRow for this request.

      Note that startRow and endRow are zero-based, inclusive at the beginning and exclusive at the end (like substring), so startRow: 0, endRow: 1 is a request for the first record.

      Returns:
      index of the first requested record (using zero-based numbering)
      See Also:
    • setStartRow

      public DSRequest setStartRow(long startRow)
      Sets the index of the first requested record.

      Note that startRow and endRow are zero-based, inclusive at the beginning and exclusive at the end (like substring), so startRow: 0, endRow: 1 is a request for the first record.

      Parameters:
      startRow - the index of the first requested record (using zero-based numbering)
      Returns:
      the DSRequest
    • getEndRow

      public long getEndRow()
      Returns the index of the last requested record. See also the notes in getStartRow() for an example of when startRow/endRow are sent.

      If getEndRow() returns DSRequest.ENDROW_UNSET (a negative value), that signifies a request for all records matching the current criteria.

      Note that startRow and endRow are zero-based, inclusive at the beginning and exclusive at the end (like substring), so startRow: 0, endRow: 1 is a request for the first record.

      Returns:
      index of the last requested record (using zero-based numbering)
      See Also:
    • setEndRow

      public DSRequest setEndRow(long endRow)
      Sets the index of the last requested record.

      Note that startRow and endRow are zero-based, inclusive at the beginning and exclusive at the end (like substring), so startRow: 0, endRow: 1 is a request for the first record.

      Parameters:
      endRow - the index of the last requested record (using zero-based numbering)
      Returns:
      the DSRequest
    • getProgressiveLoading

      public Boolean getProgressiveLoading()
      Returns true if progressive loading is enabled, false if it is disabled for this particular request or null if this was not explicitly set, meaning that OperationBinding- and DataSource-level settings will be respected and automatically switching to loading data progressively if DataSource.progressiveLoadingThreshold is exceeded would also work as expected. Search for DataSource.progressiveLoading and DataSource.progressiveLoadingThreshold in SmartClient Reference for more details.
      Returns:
      Boolean true - progressive loading is explicitly enabled; false - progressive loading is explicitly disabled; null - default value to fall back to default behavior.
    • setProgressiveLoading

      public DSRequest setProgressiveLoading(Boolean progressiveLoading)
      Sets DataSource progressive loading mode for this particular request, overriding the OperationBinding- and DataSource-level settings. This setting overrides the DataSource.progressiveLoadingThreshold setting as well, meaning that if DSRequest.progressiveLoading is explicitly set to false SmartClient won't automatically switch to loading data progressively even if DataSource.progressiveLoadingThreshold is exceeded. Search for DataSource.progressiveLoading and DataSource.progressiveLoadingThreshold in SmartClient Reference for more details.

      Note that this setting applies only to fetch requests - it has no effect if specified on any other kind of request.

      Parameters:
      progressiveLoading - boolean true - progressive loading will be enabled; false - progressive loading will be disabled.
      Returns:
      the DSRequest
    • getFieldValue

      public Object getFieldValue(Object fieldName)
      Returns the value for a particular fieldName if it exists in the valueSet, otherwise checks if the value exists in the criteria via getCriteriaValue(fieldName). This method treats the DSRequest as a single record. If the valueSet contains a value for the requested fieldName, it is returned. If not, the criteria is checked for the requested fieldName. If a value exists there, it is returned. Otherwise null is returned.

      This is a convenience method. For any given operation, a particular fieldName will usually appear in either the valueSet or criteria.

      Parameters:
      fieldName - the fieldName whose value you want to look up
      Returns:
      the value as found in valueSet or criteria
    • getCriteriaValue

      public Object getCriteriaValue(Object fieldName)
      Returns the value provided in criteria for a particular fieldName.

      If AdvancedCriteria were passed, getCriteriaValue finds the first value provided for the fieldName anywhere in the AdvancedCriteria structure, by depth-first search.

      Parameters:
      fieldName - the fieldName whose criteria value you want to look up
      Returns:
      the value found in the criteria, or null if none found
    • setCriteriaValue

      public Object setCriteriaValue(String fieldName, Object value)
      Amends the request's criteria with the restriction that the indicated field equals the provided value. If the request criteria are AdvancedCriteria, setCriteriaValue will create a Criterion based on the current textMatchStyle of the DSRequest, and combine it with the existing AdvancedCriteria with an AndCriterion. Existing Criteria referencing the indicated fieldName are not modified.

      Otherwise, setCriteriaValue updates the existing criteria Map. Any existing criterion for the indicated fieldName is overwritten.

      Parameters:
      fieldName - indicated field of criterion
      value - required value the field must equal
      Returns:
      if existing criteria is simple, and if fieldName is already referenced in the criteria, then the overwritten criterion value; otherwise null
    • setFieldValue

      public DSRequest setFieldValue(Object fieldName, Object value)
      Sets the value for a particular fieldName, in criteria or values according to the operation type.

      Generally, this method treats the criteria and values on the DSRequest as a single record: for "add" and "update" operations, the field value becomes part of the values to save. Otherwise ("fetch", "remove") the value is added to the criteria as though setCriteriaValue(String,Object) were called. For "update" operations, you set criteria values with the setCriteria(Object) or setCriteriaValue(String, Object) APIs. However, this distinction only applies for regular update-via-primaryKey, where allowMultiUpdate is not in force. Multi-update DSRequests must place the entire state of the update, both criteria and values, in the DSRequest values.

      Parameters:
      fieldName - the fieldName whose value you want to set
      value - the value to set for the field
      Returns:
      this DSRequest for method chaining
    • getDataSourceName

      public String getDataSourceName()
      Returns the dataSourceName for this DSRequest. This will be the same name you passed as the dataSource attribute to the databound component issuing this request.
      Returns:
      name of the datasource for this DSRequest
    • getDataSource

      public DataSource getDataSource() throws Exception
      Returns an instance of class DataSource for this DSRequest.
      Returns:
      dataSource instance for this DSRequest
      Throws:
      Exception - if an error occurs while retrieving the DataSource
      See Also:
    • getTenantId

      public String getTenantId()
      Returns the tenant ID associated with this DSRequest.
      Returns:
      the renant ID associated with this DSRequest
      See Also:
    • setTenantId

      public DSRequest setTenantId(String tenantId)
      Sets the tenant ID associated with this DSRequest
      Parameters:
      tenantId - the tenant ID to set for this request
      Returns:
      the DSRequest
      See Also:
    • getValidationMode

      public String getValidationMode()
      Returns the validationMode associated with this DSRequest
      Returns:
      the validationMode associated with this DSRequest
    • setValidationMode

      public DSRequest setValidationMode(String validationMode)
      Sets the validationMode associated with this DSRequest
      Returns:
      the DSRequest
    • getPendingAddFlag

      public boolean getPendingAddFlag()
      Returns the pendingAdd flag associated with this DSRequest
      Returns:
      the pendingAdd flag associated with this DSRequest
    • setPendingAddFlag

      public DSRequest setPendingAddFlag(boolean pendingAdd)
      Sets the pendingAdd flag associated with this DSRequest
      Returns:
      the DSRequest
    • validate

      public ErrorReport validate() throws Exception
      Performs validation on the values in this DSRequest. The values provided as part of this DSRequest are tested against the validators defined on a per-field basis in the dataSource (.ds.xml file).

      If validation is successful for all fields, this method returns null. Otherwise it returns an ErrorReport for the first record that encountered a validation error.

      Returns:
      ErrorReport or null if there were no errors.
      Throws:
      Exception
      See Also:
    • getGenerateRelatedUpdates

      public Boolean getGenerateRelatedUpdates()
      Should related updates be generated in DSResponse. Related updates issue additional requests to database thus reducing performance. By default (if value set to null) related updates will be generated only for "add" and "update" operations because related objects are loaded anyway and performance impact is minimal.

      Related updates for "remove" operation will not be generated by default (if value set to null). Related updates generation loads related objects from database while simple "remove" operation does not. Depending on database structure performance impact can be significant if value set to true.

      Returns:
      Boolean true - related updates will be generated; false - related updates will not be generated; null - related updates will be generated only for "add" and "update" operations, related updates will not be generated for "remove" operation.
    • convertRelativeDates

      public void convertRelativeDates()
      Converts any relative dates found in this requests criteria into absolute dates relative to when this method is run.

      Note: This conversion happens internally and the criteria on this request will be modified.

      See Also:
    • call

      public DSResponse call() throws Exception
      Calls through to execute(). Be careful about resources used by the DSRequest - you may want to set setFreeOnExecute() to avoid having to wait for DSRequest garbage collection to clean up any consumed resources. On the other hand, if your logic depends on streaming data that would be terminated by freeing on execute, you may need to instead adjust you thread pool according to server demands to ensure you don't experience memory pressure.
      Throws:
      Exception
      See Also:
    • execute

      public DSResponse execute() throws Exception
      Executes this DSRequest and returns a DSResponse. If an application is defined for this request, the execution is dispatched through that application. Otherwise, the execution is dispatched through the DataSource layer.
      Specified by:
      execute in class BaseRequest<DSRequest,DSResponse>
      Returns:
      a response that extends BaseResponse
      Throws:
      Exception - if an error occurs during request execution
    • addToTemplateContext

      public DSRequest addToTemplateContext(String name, Object value)
      Same as the three-argument version, but the third argument (isSnippet) is always false.
      Parameters:
      name - the name of the new object as it should appear in the Velocity namespace
      value - arbitrary Java object
      Returns:
      the DSRequest
    • addToTemplateContext

      public DSRequest addToTemplateContext(String name, Object value, boolean isSnippet)
      If you're using the Velocity-based SQL Templating, you can make additional Java objects available to the the template context for this request only by calling this method. To make objects available to every request in a queue, see DSTransaction.addToTemplateContext()

      If you would like to add Java objects to all Velocity templates, you can do so via the Velocity Tools mechanism described here: http://velocity.apache.org/tools/releases/2.0/index.html Just add the velocity tools jars to your deployment and place your tools.xml configuration file in the CLASSPATH (typically WEB-INF/classes).

      The isSnippet parameter controls whether the framework treats the context object as a regular context variable, or a user-defined snippet of text. If isSnippet is true, the context object will be evaluated through Velocity immediately prior to the main Velocity evaluation taking place. This means that you can create context variables that themselves contain variable references, and those references will be correctly resolved in the final output. Read the "User-defined snippets" section of the "customQuerying" article in the client-side docs for more details.

      Parameters:
      name - the name of the new object as it should appear in the Velocity namespace
      value - arbitrary Java object
      isSnippet - Is the context object a user-defined snippet?
      Returns:
      the DSRequest
    • addToScriptContext

      public DSRequest addToScriptContext(String name, Object value)
      If you're using any of the script-based, server-side request or response transformation features - transformRequestScript, transformResponseScript or fieldValueScript - you can make additional Java objects available to the script, for this request only, by calling this method. To make objects available to every request in a queue, see DSTransaction.addToScriptContext()

      For example, set up a string in Java code:

           dsRequest.addToScriptContext("mySimpleString", "This is a test");
       
      and then use that string in your transformation script:
           <DataSource ID="myDS">
               <transformResponseScript language="groovy">
                   // Add a property to the response object
                   responseObject["testingTransform"] = mySimpleString;
                   . . .
               </transformResponseScript>
               . . .
           </DataSource>
      Parameters:
      name - the name of the new object as it should be made available to the script
      value - arbitrary Java object
      Returns:
      the DSRequest
    • removeFromScriptContext

      public DSRequest removeFromScriptContext(String name)
      Removes a variable from the script context
      Parameters:
      name - the name of the object to remove
      Returns:
      the DSRequest
      See Also:
    • setAllowMultiUpdate

      public DSRequest setAllowMultiUpdate(boolean newValue)
      Sets an internal flag for this DSRequest to determine whether updates and deletes are allowed in the absence of primaryKey fields. If set to false:
      • prevents requests making sweeping DB changes even if server code isn't written to carefully enforce what can be updated
      • provides safeguards for server code
      • allows convenient updates and deletes where you just pass the record in question and rely on the DataSource layer to extract primaryKeys
      Note that this property is mainly intended for use with DSRequests that are created by hand on the server side. For ordinary DSRequests that come from the client, the ability to do multi-updates is more conveniently controlled by creating an operationBinding with the allowMultiUpdate property set. See the client-side documentation for OperationBinding for details. Note that operationBinding.allowMultiUpdate, if present, takes priority over this method.

      Note that DSRequests with allowMultiUpdate in force, either because this method has been called or because of the operationBinding setting, must include the entire state of the update - both the values and the criteria - in the DSRequest values as discussed here

      Note that if not set, or set to null this is controlled by dataSource.defaultMultiUpdatePolicy, see client docs for details.

      Parameters:
      newValue - true to allow multi-updates; false to restrict updates so that they can affect just one single record, identified by primaryKey values in the record provided
      Returns:
      the DSRequest
    • setAllowArbitrarySubqueries

      public DSRequest setAllowArbitrarySubqueries(boolean newValue)
      Sets an internal flag for this DSRequest to determine whether arbitrary subqueries should be permitted for this DSRequest. Only applicable to server-initiated DSRequests; the system ignores this setting for client-initiated requests. If set to false (the default), the system will limit subqueries in this server-initiated to the same set of properties that are allowed for ordinary client requests (scan the client-side documentation for "AdvancedCriterionSubquery" for further details). If set to true, we will accept any DSRequest setting in a subquery

      Limiting server-initiated DSRequests by default is a safety measure: by ensuring that you have to explicitly allow arbitrary subqueries, we hope to encourage careful consideration of the potential security implications. For example, a server-initiated DSRequest could take untrusted criteria from a client request and use it in a subquery to access something like a protected Stored Procedure that is accessible as a customized "fetch" operationBinding. This would only be allowed if allowArbitrarySubqueries is explicitly set on

      Parameters:
      newValue - true to allow arbitrary subqueries (anyDSRequest property is allowed in a subquery); false to restrict subqueries so that they are only allowed to specify proeprties that are allowed for an ordinary client request
      Returns:
      the DSRequest
    • getOutputs

      public List getOutputs()
      Returns the list of output fields requested by the client, or set manually by a server-side call to setOutputs(java.util.List). Will return null if the client did not send a list of outputs and no manual server-side call to setOutputs() has been made. Note that this is not the definitive list of fields to be returned to the client - for that, see getConsolidatedOutputs()
      Returns:
      List the list of requested outputs as a List of String, or null
      See Also:
    • setOutputs

      public DSRequest setOutputs(List outputs)
      Sets the list of output fields to be returned by this request. If passed null, resets the list of fields to return so that normal rules apply (so basically all fields are returned - scan the client-side docs for "dropExtraFields" for more information).

      This method is called during DSRequest construction to set the list of output fields requested by the client. Therefore, you can call this method from a DMI, custom DataSource or other custom server side code to override the output fields requested by the client. Note that this is not the definitive list of fields to be returned to the client - for that, see getConsolidatedOutputs()

      Parameters:
      outputs - the list of requested outputs as a List of String, or null
      Returns:
      the DSRequest itself
      See Also:
    • getAdditionalOutputs

      public List getAdditionalOutputs()
      Creates and returns a list of DSFields specified in this DSRequest's "additionalOutputs" property. "additionalOutputs" is a comma separated String of requested fields not defined in the dataSource directly. The field is defined in the form of "fieldName:includeFrom".
      Returns:
      List of DSFields specified in the DSRequest's "additionalOutputs" property.
    • getExportResults

      public boolean getExportResults()
      Whether this request will result in an export, as opposed to a normal DSResponse.
      Returns:
      true if results are to be exported
    • setExportResults

      public DSRequest setExportResults(Boolean exportResults)
      Set the flag indicating whether the results of this request should be exported
      Parameters:
      exportResults - true if results are to be exported
      Returns:
      the DSRequest
    • setExportAs

      public DSRequest setExportAs(String exportAs)
      The format in which to export data. If unset, the default is "csv".
      Parameters:
      exportAs - one of "csv", "xml", "json", "xls"
      Returns:
      the DSRequest
    • setExportDelimiter

      public DSRequest setExportDelimiter(String exportDelimiter)
      The delimiter to use for CSV-type exports
      Parameters:
      exportDelimiter - the character to use as a delimiter in CSV exports
      Returns:
      the DSRequest
    • setExportTitleSeparatorChar

      public DSRequest setExportTitleSeparatorChar(String exportTitleSeparatorChar)
      The separator character to replace spaces with in XML field-titles.
      Parameters:
      exportTitleSeparatorChar - the character to replace spaces with in XML field-titles.
      Returns:
      the DSRequest
    • setExportFilename

      public DSRequest setExportFilename(String exportFilename)
      The name of the file to save the exported data into, if we are exporting to the server filesystem. This is also used to name the downloaded file if we are exporting to the client, but only if the server.properties flag RPCManager.downloadsRelyOnFilenameInURL is set false. The default value of true for that flag means that the server will always use the name that the client requested for the downloaded file, so a call to this method will have no effect (the reason for this default is that it gives the most predictably correct results when dealing with filenames expressed in non-Latin character sets).

      When no filename is provided, the default is "Results".

      Parameters:
      exportFilename - the name of the file to save the exported data into
      Returns:
      the DSRequest
    • setExportPath

      public DSRequest setExportPath(String exportPath)
      Optional path to apply when saving exported data to the filesystem, relative to the base location specified in server.properties setting "export.location"
      Parameters:
      exportPath - Path to apply
      Returns:
      the DSRequest
    • setExportDisplay

      public DSRequest setExportDisplay(String exportDisplay)
      How should the exported data be displayed to the user? If not provided, the default is "window".
      Parameters:
      exportDisplay - one of "window" or "download"
      Returns:
      the DSRequest
    • setLineBreakStyle

      public DSRequest setLineBreakStyle(String lineBreakStyle)
      The linebreak style in the exported data. One of "default", "unix, "mac" or "dos".
      Parameters:
      lineBreakStyle - the linebreak style to use in the exported data
      Returns:
      the DSRequest
    • setExportFields

      public DSRequest setExportFields(List exportFields)
      The list of fields to export.
      Parameters:
      exportFields - the list of field-names to export
      Returns:
      the DSRequest
    • setExportFieldTitles

      public DSRequest setExportFieldTitles(Map exportFieldTitles)
      A map containing the titles to use for each field to be exported.
      Parameters:
      exportFieldTitles - the list of field-names to export
      Returns:
      the DSRequest
    • setHashedFields

      public DSRequest setHashedFields(List hashedFields)
      A list of fields declared with storeWithHash that already contain hashed values in this request, and that therefore should not be rehashed. The common case is where those values have been copied from an existing (already hashed) record.
      Parameters:
      hashedFields - the list of field names that already have hashed content
      Returns:
      the DSRequest
    • setExportHeader

      public DSRequest setExportHeader(String exportHeader)
      Optional text to appear at the top of the export file.
      Parameters:
      exportHeader - Optional text to appear above the data
      Returns:
      the DSRequest
    • setExportHeaderless

      public DSRequest setExportHeaderless(boolean exportHeaderless)
      This property allows omitting column names from CSV and Excel exports (no effect on JSON or XML exports).
      Parameters:
      exportHeaderless - If true, the column names will be omitted from CSV and Excel exports.
      Returns:
      the DSRequest
    • setExportFooter

      public DSRequest setExportFooter(String exportFooter)
      Optional text to appear at the bottom of the export file.
      Parameters:
      exportFooter - Optional text to appear below the data
      Returns:
      the DSRequest
    • setStreamResults

      public DSRequest setStreamResults(boolean streamResults)
      If true, results will be streamed one record at a time; if false, we will read all records into memory at once
      Parameters:
      streamResults - true to cause data to be streamed
      Returns:
      the DSRequest
    • shouldStreamResults

      public boolean shouldStreamResults()
      If true, results will be streamed one record at a time; if false, we will read all records into memory at once. Scan the client-side documentation for "streamResults"
      Returns:
      true if results should be streamed, otherwise false
    • setExportToFilesystem

      public DSRequest setExportToFilesystem(boolean exportToFilesystem)
      If true, we export the data to the file named by propertyexportFilename on the server filesystem. See also setExportToClient(boolean)

      Note this is automatically set to true if setExportTo(java.io.OutputStream) is called.

      Parameters:
      exportToFilesystem - true to cause the export data to be written to the server filesystem
      Returns:
      the DSRequest
    • setExportToClient

      public DSRequest setExportToClient(boolean exportToClient)
      If true, we download the exported data to the client. If setExportToFilesystem(boolean) is also set, we will both download the exported data and write it to a filesystem file on the server. If neither of these is set, the export operation no-ops.
      Parameters:
      exportToClient - true to cause the exported data to be downloaded to the client
      Returns:
      the DSRequest
    • getExportTo

      public OutputStream getExportTo()
      Returns the OuputStream we will use for data export. If you have not set this explicitly with the setExportTo(OutputStream) API, it will be null.
      Returns:
      The export OutputStream
    • setExportTo

      public DSRequest setExportTo(OutputStream exportOutputStream)
      Sets the OuputStream we will use for data export (this means exports to CSV, XML, JSON and Excel formats; PDF exports are "content exports" and are different). This API allows you to arrange for other export scenarios than the two built-in options (download to client and write to filesystem). If you set this property, it overrides the default OutputStream we would normally create for a filesystem export; in other words, we will export to your OutputStream rather than to a filesystem file.

      Also note that we perform the export synchronously as part of the DSRequest's execute flow when a user-provided OutputStream is in place. This allows you to make use of the OutputStream immediately after executing the request from a DMI, like this:

         OutputStream myStream = new MyOutputStream();
         dsRequest.setExportTo(myStream);
         DSResponse resp = dsRequest.execute();
         // Do something with "myStream" here
       
      Parameters:
      exportOutputStream - An OutputStream to use for the export
      Returns:
      The DSRequest itself
      See Also:
    • getREST

      public Boolean getREST()
      Returns true if it is REST request.
      Returns:
      Boolean true - REST request.
    • setREST

      public DSRequest setREST(Boolean isREST)
      Sets flag indicating whether it is REST request.
      Parameters:
      isREST - Boolean true - REST request.
      Returns:
      the DSRequest
    • getRawREST

      public Boolean getRawREST()
      Returns true if it is a raw REST mode request.
      Returns:
      Boolean true - raw REST request.
    • setRawREST

      public DSRequest setRawREST(Boolean isRawREST)
      Sets flag indicating whether it is a raw REST mode request.
      Parameters:
      isRawREST - Boolean true - raw REST request.
      Returns:
      the DSRequest
    • getDataFormat

      public String getDataFormat()
      Returns data format for REST request.
      Possible values: "xml" and "json".
      Returns:
      String REST request data format.
    • setDataFormat

      public DSRequest setDataFormat(String dataFormat)
      Sets data format for REST request.
      Parameters:
      dataFormat - String REST request data format. Accepted values: 'xml' or 'json'.
      Returns:
      the DSRequest
    • getWrapJSONResponses

      public Boolean getWrapJSONResponses()
      Returns true if JSON responses should be wrapped with markers.
      Returns:
      Boolean true - JSON responses will be wrapped with markers; false - JSON responses will contain plain objects.
    • setWrapJSONResponses

      public DSRequest setWrapJSONResponses(Boolean wrapJSONResponses)
      Sets flag should JSON responses be wrapped with markers.
      Parameters:
      wrapJSONResponses - boolean true - JSON responses will be wrapped with markers; false - JSON responses will contain plain objects.
      Returns:
      the DSRequest
    • getJsonPrefix

      public String getJsonPrefix()
      Returns prefix marker for JSON responses.
      Returns:
      String JSON prefix marker.
    • setJsonPrefix

      public DSRequest setJsonPrefix(String jsonPrefix)
      Sets prefix marker for JSON responses.
      Parameters:
      jsonPrefix - String JSON prefix marker.
      Returns:
      the DSRequest
    • getJsonSuffix

      public String getJsonSuffix()
      Returns suffix marker for JSON responses.
      Returns:
      String JSON suffix marker.
    • setJsonSuffix

      public DSRequest setJsonSuffix(String jsonSuffix)
      Sets suffix marker for JSON responses.
      Parameters:
      jsonSuffix - String JSON suffix marker.
      Returns:
      the DSRequest
    • setUserRoles

      public DSRequest setUserRoles(String rolesString)
      Set the user roles associated with this request.
      Parameters:
      rolesString - A comma-separated String containing the user roles to set for this request
      Returns:
      this DSRequest, allowing for method chaining.
    • setUserRoles

      public DSRequest setUserRoles(String... roles)
      Set the user roles associated with this request.
      Parameters:
      roles - the user roles to set for this request.
      Returns:
      this DSRequest, allowing for method chaining.
    • setUserRoles

      public DSRequest setUserRoles(List<String> userRoles)
      Set the user roles associated with this request.

      These roles are compared against when declarative security runs against this request. If this method is called this request will also be marked as a client request which in turn enables declarative security checks for it.

      Parameters:
      userRoles - the user roles to set for this request.
      Returns:
      this DSRequest, allowing for method chaining.
    • setUserId

      public DSRequest setUserId(String userId)
      Set the user ID associated with this request.

      This value will be used by the framework to populate fields of types "creator" and "modifier". This API is intended for use when you are a using some custom authentication scheme - it is unnecessary if you are using the Servlet API for authentication, because we will default to using the value returned by HttpServletRequest.getRemoteUser().

      If this method is called this request will also be marked as a client request which in turn enables declarative security checks for it.

      Parameters:
      userId - the user id to set for this request.
      Returns:
      this DSRequest, allowing for method chaining.
    • getHttpServletRequest

      public jakarta.servlet.http.HttpServletRequest getHttpServletRequest()
      Returns the HttpServletRequest associated with this DSRequest. Note that a DSRequest does not need to operate in the context of the Servlet API; this method will return null if you are not running in a servlet container. It is not recommended that you use this value for systems where there is any chance of having to operate outside of a web app, or be usable with automated test software.
      Returns:
      The HttpServletRequest to use for this request, or null if this request is not running in the context of a web application
    • getServletContext

      public jakarta.servlet.ServletContext getServletContext()
      Returns the ServletContext associated with this DSRequest. Note that a DSRequest does not need to operate in the context of the Servlet API; this method will return null if you are not running in a servlet container. It is not recommended that you use this value for systems where there is any chance of having to operate outside of a web app, or be usable with automated test software.
      Returns:
      The ServletContext to use for this request, or null if this request is not running in the context of a web application
    • setRequestContext

      @Deprecated public DSRequest setRequestContext(RequestContext context)
      Deprecated.
    • getAttribute

      public Object getAttribute(String key)
      Returns an Object that has previously been stored in this DSRequest's attribute map. This method intentionally mirrors the method of the same name available on HttpServletRequest, and is provided as an alternative way to add objects to a DSRequest without introducing a dependency on the Servlet API.
      Parameters:
      key - The key of the object in the DSRequest's attribute map
      Returns:
      the Object associated with the parameter key
      See Also:
    • getAttributeNames

      public Iterator getAttributeNames()
      Returns an Iterator that can be used to obtain all the keys in the DSRequest's attribute map. This method intentionally mirrors the method of the same name available on HttpServletRequest (though it returns an Iterator rather than an Enumeration), and is provided as an alternative way to add objects to a DSRequest without introducing a dependency on the Servlet API.
      Returns:
      an Iterator that can be used to obtain all the keys in the DSRequest's attribute map
      See Also:
    • setAttribute

      public DSRequest setAttribute(String key, Object value)
      Stores an object in this DSRequest's attribute map, associated with the passed key. This method intentionally mirrors the method of the same name available on HttpServletRequest, and is provided as an alternative way to add objects to a DSRequest without introducing a dependency on the Servlet API.

      Attributes set on the DSRequest are not serialized and sent to the browser. Custom attributes exist solely for passing extra information between different server-side subsystems that might process the DSRequest. For example: Java logic in a DMI might set attributes on a DSRequest to cause differences in processing by a custom DataSource that checks for those attributes.

      Parameters:
      key - The key of the object in the DSRequest's attribute map
      value - The object to store
      Returns:
      the DSRequest
      See Also:
    • removeAttribute

      public DSRequest removeAttribute(String key)
      Removes an Object that has previously been stored in this DSRequest's attribute map. This method intentionally mirrors the method of the same name available on HttpServletRequest. It is provided as an alternative, to avoid introducing a dependency on the Servlet API.
      Parameters:
      key - The key of the object in the DSRequest's attribute map
      See Also:
    • isAuditRequest

      public boolean isAuditRequest()
      Returns true if this DSRequest is running as part of an automatic audit process. Your DMIs, scripts and custom DataSource implementations can use this API to determine if a fetch is running as part of the audit process, in case they need to do something special in that case (for example, if your default fetch operations filter out certain records or fields, but you need those filtered elements in order to write a complete audit record)
    • shouldJoinTransaction

      public Boolean shouldJoinTransaction()
      Returns the join transaction setting for this DSRequest. DSRequests running in a request queue can be configured so that they are committed as a single database transaction. Ordinarily, this is configured in SmartClient .properties files, or in DataSource definitions. However, it is possible to override these configuration settings by calling setJoinTransaction(Boolean), which overrides any setting derived from configuration.

      This method is only applicable to DSRequests for a DataSource that supports transaction management. SmartClient's built-in SQL and Hibernate DataSources both have transaction support. If you intend to write a DataSource that supports transactions, you should call this method to determine if user code has overridden configuration settings for this DSRequest.

      See the client-side documentation for details of configuring automatic transaction support.

      Returns:
      Boolean.TRUE or Boolean.FALSE is this DSRequests join policy has been overridden; null if the normal system behavior of using configuration settings is in force
    • setJoinTransaction

      public DSRequest setJoinTransaction(Boolean newValue) throws com.isomorphic.datasource.DSRequestAlreadyStartedException
      Sets the join transaction setting for this DSRequest. DSRequests running in a request queue can be configured so that they are committed as a single database transaction. Ordinarily, this is configured in SmartClient .properties files, or in DataSource definitions. However, it is possible to override these configuration settings by calling this method, which overrides any setting derived from configuration. It also overrides any RPCManager-level override that has been put in place for this particular queue by calling setTransactionPolicy

      For a manually created dsRequest (one not sent by the client), in order to participate in the current automatic transaction, setRPCManager(RPCManager) must be called. Then, the dsRequest will automatically participate in the current automatic transaction (if there is one) without the need to call this method.

      This method is only applicable to DSRequests for a DataSource that supports transaction management. SmartClient's built-in SQL and Hibernate DataSources both have transaction support.

      Note that this method can only be called on a DSRequest that has not yet started processing; it will fail with an exception if it is called on a request that has already started.

      See the client-side documentation for details of configuring automatic transaction support.

      Parameters:
      newValue - Set true to force this DSRequest's update to start or join a transaction; false to force this DSRequest's update to be auto-committed independently of any other update in the queue; null to revert to configuration settings (this is the default if this method is never called)
      Returns:
      the DSRequest
      Throws:
      com.isomorphic.datasource.DSRequestAlreadyStartedException - if this DSRequest has already started processing
      See Also:
    • freeAllResources

      public DSRequest freeAllResources()
      Frees all shared resources (for example, DataSource instances and database connections) used by this DSRequest.

      Typically, there is no need to call freeAllResources because it is automatically handled by the framework. You only need to call this API when all of the following apply:

      1. You are using a DSRequest that was created server-side by your code, AND
      2. You have not called setRPCManager() on the request, AND
      3. You have explicitly called setFreeOnExecute(false) on the DSRequest, or the default setting of freeOnExecute is false for this type of request.
      Regarding 2), it would be normal practice to call setRPCManager() or setDSTransaction() on server-created DSRequests because this is required in order to participate in automatically managed transactions.

      Regarding 3), any DSRequest that targets a SQLDataSource and retrieves data from a binary column (CLOB) is freeOnExecute:false by default, since otherwise most JDBC drivers will close the InputStream used to read binary data.

      Also, any DSRequest targeting HibernateDataSource or JPADataSource is freeOnExecute:false by default in order to allow traversing lazy entity associations.

      Note that the resources freed by this API are made immediately available to other threads: do not cache DataSource instances or other resources and attempt to reuse them after calling this API. In general, use this API only if you are sure you have to (because you have a DSRequest like the one described above), and even then use it with care; ideally, call it as the last thing you do immediately before your DMI method ends.

      Overrides:
      freeAllResources in class BaseRequest<DSRequest,DSResponse>
      Returns:
      the DSRequest
    • setFreeOnExecute

      public DSRequest setFreeOnExecute(boolean freeOnExecute)
      Ordinarily, this value is managed transparently by the RPCManager controlling the queue that the DSRequest is part of. The only time you should consider using it in application code is when you have entirely server-side DSRequests, because these will not be managed by an RPCManager.

      If you pass true to this method, it causes resources used by the DSRequest (including the DataSource object and implementation-specific resources such as database connections) to be freed early - as soon as the DSRequest has finished executing. If you pass false, it causes those resource to be freed late - during final cleanup by the RPCManager if setRPCManager() has been called, otherwise, when your code manually calls freeAllResources(), otherwise, by the DSRequest's finalizer when garbage collection occurs.

      Generally, you should use freeOnExecute(true) - the default - as this is the most efficient thing to do. However, there are times when you need the resources to be retained - for example, if you have a server-side DSRequest that streams its results.

      See freeAllResources() for a further discussion of scenarios where immediate cleanup is not desirable.

      Parameters:
      freeOnExecute - as described above
      Returns:
      the DSRequest
    • getConsolidatedOutputs

      public List getConsolidatedOutputs()
      Returns the consolidated list of fields that will be returned to the client. This takes all of the following into account:
      • The "outputs" parameter sent from the client on the DSRequest, if any
      • The "outputs" property declared on the OperationBinding, if any
      • Extra fields that are dynamically included due to a reference in the DSRequest's criteria property
      • includeFrom fields (both declarative and dynamic) that must be excluded because they are misconfigured in some way (for example, they refer to a non-existent DataSource)
      Note that if none of the above apply, getConsolidatedOutputs() will return null; this means that default behavior will apply for this request (see the client-side docs for DSRequest.dropExtraFields). Note that, whether or not consolidatedOutputs is null, the actual fields returned to the client can still be affected by declarative security settings. See getDroppedFields()
      Returns:
      List the consolidated list of output fields as a List of String, or null
      See Also:
    • getDroppedFields

      public List getDroppedFields()
      Returns the list of fields that have been or will be dropped for this DSRequest as a result of applying field-level declarative security rules. See the client-side docs for DataSourceField.viewRequiresAuthentication, and the related properties that it links to.

      Note, the list returned by this method is a copy, and thus should be considered read-only.

      Returns:
      List the consolidated list of output fields as a List of String, or null
      See Also:
    • addToCriteria

      public DSRequest addToCriteria(String fieldName, Object value) throws Exception
      If the criteria is currently simple, this method just adds the provided fieldName and value as an extra key/value pair to this DSRequest's existing criteria.

      If the criteria is already Advanced and either:

      • The field is of base type "text", or
      • The fields is of base type "integer" or "float" AND the supplied value is a String
      this method will use the operator that corresponds to the textMatchStyle of this DSRequest and will add a criterion of the form { fieldName textMatchStyle value } to this DSRequest's existing criteria. Otherwise, it will add a criterion of the form { fieldName "equals" value } to this DSRequest's existing criteria.

      Note that this is the only version of addToCriteria() that attempts to automatically preserve simple criteria semantics as described above. If you do not want this behavior, use one of the other signatures of this method.

      Parameters:
      fieldName - The field name to use in the criteria
      value - The filter value to apply
      Returns:
      the DSRequest
      Throws:
      Exception
    • addToCriteria

      public DSRequest addToCriteria(String fieldName, String operator, Object value) throws Exception
      Adds a criterion of the form { fieldName operator value } to this DSRequest's existing criteria. This is a convenience method; it is equivalent to calling the addToCriteria(Criterion), but passing criterion data as individual parameters.
      Parameters:
      fieldName - The field name to use in the criteria
      operator - The operatorId to use
      value - The filter value to apply
      Returns:
      the DSRequest
      Throws:
      Exception
    • addToCriteria

      public DSRequest addToCriteria(String fieldName, String operator, Object[] value) throws Exception
      Creates a SetCriterion with the provided values, then this SetCriterion is added to this DSRequest's existing criteria. This is a convenience method; it is equivalent to calling the addToCriteria(Criterion), but passing criterion data as individual parameters.
      Parameters:
      fieldName - The field name to use in the criteria
      operator - The operatorId to use
      value - An array of values
      Returns:
      the DSRequest
      Throws:
      Exception
    • addToCriteria

      public DSRequest addToCriteria(String fieldName, OperatorBase operator, Object value) throws Exception
      Adds a criterion of the form { fieldName operator value } to this DSRequest's existing criteria. This is a convenience method; it is equivalent to calling the addToCriteria(Criterion), but passing criterion data as individual parameters. Note that this method uses OperatorBase parameter as operator ID to avoid typos.
      Parameters:
      fieldName - The field name to use in the criteria
      operator - The operatorBase to use
      value - The filter value to apply
      Returns:
      the DSRequest
      Throws:
      Exception
    • addToCriteria

      public DSRequest addToCriteria(String fieldName, OperatorBase operator, Object[] value) throws Exception
      Creates a SetCriterion with the passed parameters, then this SetCriterion is added to this DSRequest's existing criteria.
      This is a convenience method; it is equivalent to calling the addToCriteria(Criterion), but passing criterion data as individual parameters. Note that this method uses OperatorBase parameter as operator ID to avoid typos.
      Parameters:
      fieldName - The field name to use in the criteria
      operator - The operatorBase to use
      value - An array of values
      Returns:
      the DSRequest
      Throws:
      Exception
    • addToCriteria

      public DSRequest addToCriteria(String fieldName, String operator, Object value, Object start, Object end) throws Exception
      Adds a criterion to this DSRequest's existing criteria. This is a convenience method; it is equivalent to calling the addToCriteria(Criterion), but passing criterion data as individual parameters.
      Parameters:
      fieldName - The field name to use in the criteria
      operator - The operatorId to use
      value - The filter value to apply, for comparison operators like "contains"
      start - The range-start value to apply, for range operators like "between"
      end - The range-end value to apply, for range operators like "between"
      Returns:
      the DSRequest
      Throws:
      Exception
    • addToCriteria

      public DSRequest addToCriteria(Criterion criterion) throws Exception
      Adds a Criterion instance to this DSRequest's existing criteria. This method is used by the transaction chaining feature to apply criteria additions; it can also be called by arbitrary server-side code to add a criterion to simple or AdvancedCriteria. Note that this method always converts an existing simple criteria to an AdvancedCriteria. If you simply wish to add further key/value pairs to an existing simple criteria, use the two argument signature of this method.

      If the DSRequest's criteria is simple, the simple criteria is converted to an equivalent AdvancedCriteria and then processed as if the criteria had been Advanced all along, which is to amend the criteria as follows:

      • If the topmost operator is "and", we add the new criterion described above as an additional criterion.
      • Otherwise, we create a new top-level AdvancedCriteria map, with an operator of "and". This is then set to have two elements to its criteria: the previous top-level criteria and the new criterion described above.
      Hence, in all cases, the effect is to apply the new criterion as an extra condition that must be met in order for a record to be selected.
      Parameters:
      criterion - The criterion to use in the criteria
      Returns:
      the DSRequest
      Throws:
      Exception
    • getMissingPrimaryKeysForAdd

      public List getMissingPrimaryKeysForAdd() throws Exception
      Validates that this DSRequest has a value present for every non-generated primaryKey. During "add" operations, it is valid (and sometimes even required, depending on the database in use) for fields of type "sequence" to be missing from the values, but all other types of primaryKey must be present. This method is called by SmartClient Server's built-in DataSource implementations immediately before they generate SQL/HQL/JPQL, in order to give custom server-side code in DMIs and Custom DataSource subclasses a chance to add key values to the request before rejecting it.

      In a completely custom DataSource (ie, one that extends BasicDataSource), you should add a call to this method if you want the protection it provides against null key values. The simplest thing to do is what the built-in DataSources do - throw an UpdateWithoutPKException if this method returns a non-empty List.

      Note that this method honors the operationBinding setting "allowMultiUpdate" - if that property is set for the operation this DSRequest is running, this method always returns an empty List. Also, it is possible to switch off key checking for "add" operations altogether by setting the property validate.primaryKeys.for.add to false in your server.properties file. Finally, be aware that primaryKey fields that declare a customInsertExpression are never considered to have "missing values", because it is assumed that the custom expression will cause a value to appear at SQL generation or execution time.

      Returns:
      the List of non-generated primaryKey fields that are missing from this DSRequest, or an empty List if there are no such fields, or key checking is inoperative either globally or for the operationBinding currently in force
      Throws:
      Exception
    • setSkipCacheSync

      public void setSkipCacheSync(boolean skipCacheSync)
      Enable or disable cacheSync on this request. Advanced usage used to speed up population of records. When set, the record-as-saved will not be available on the response.
      Parameters:
      skipCacheSync - true if cacheSync must be skipped, false if it must be performed.
    • isCacheSyncSkipped

      public boolean isCacheSyncSkipped()
      Check if cacheSync must be skipped for this request.
      Returns:
      true if cacheSync must be skipped, false if it must be performed.
    • setSkipAudit

      public DSRequest setSkipAudit(boolean skipAudit)
      Enable or disable auditing on this request.
      Parameters:
      skipAudit - true if auditing must be skipped, false if it must be performed.
      Returns:
      the DSRequest
    • isAuditSkipped

      public boolean isAuditSkipped()
      Check if auditing must be skipped for this request.
      Returns:
      true if auditing must be skipped, false if it must be performed.
    • setCanSyncCache

      public void setCanSyncCache(boolean canSyncCache)
      See the client-side docs for OperationBinding.canSyncCache for a complete reference.
      Parameters:
      canSyncCache -