com.isomorphic.datasource

## Class DataSource

- com.isomorphic.datasource.DataSource

- All Implemented Interfaces:
    IToJSON
  Direct Known Subclasses:
    BasicDataSource

      public class DataSource
      implements IToJSON

  A DataSource is metadata that provides a high-level, implementation independent description of a set of permanently stored objects that will be manipulated within a SmartClient application.

  The server-side DataSource object supports declarative validation, XPath-based mapping of DataSource fields to Java Objects and XML structures, and dynamic instantiation from XML. See the client reference for the client-side capabilities of DataSource objects.

  See Also:
    Serialized Form

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `protected static java.util.Map` | `inInitState` Holds data sources which are in init state.
    `static java.lang.String` | `OP_ADD` Constant specifying the add operation.
    `static java.lang.String` | `OP_CLIENT_EXPORT` Constant specifying a clientExport operation.
    `static java.lang.String` | `OP_CUSTOM` Constant specifying a custom operation.
    `static java.lang.String` | `OP_FETCH` Constant specifying the fetch operation.
    `static java.util.Set` | `OP_FILE_SOURCE` Constant specifying the fileSource operations.
    `static java.lang.String` | `OP_GET_FILE` Constant specifying a getFile operation.
    `static java.lang.String` | `OP_HAS_FILE` Constant specifying a hasFile operation.
    `static java.lang.String` | `OP_LIST_FILES` Constant specifying a listFiles operation.
    `static java.lang.String` | `OP_REMOVE` Constant specifying the remove operation.
    `static java.lang.String` | `OP_REMOVE_FILE` Constant specifying a removeFile operation.
    `static java.lang.String` | `OP_RENAME_FILE` Constant specifying a renameFile operation.
    `static java.lang.String` | `OP_SAVE_FILE` Constant specifying a saveFile operation.
    `static java.lang.String` | `OP_UPDATE` Constant specifying the update operation.
    `static java.lang.String` | `OP_VALIDATE` Constant specifying the validate operation.

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `long` | `add(java.lang.Object values)` This convenience method is the equivalent of creating a DSRequest with an operationType of "add", calling setValues() on it, and then calling its execute() method.
    `static void` | `addDynamicDSGenerator(DynamicDSGenerator ddsg)` Registers the parameter DynamicDSGenerator with the DataSource system by placing it at the top of a stack of DynamicDSGenerators.
    `static void` | `addDynamicDSGenerator(DynamicDSGenerator ddsg, java.util.regex.Pattern regex)` Registers the parameter DynamicDSGenerator with the DataSource system.
    `static void` | `addDynamicDSGenerator(DynamicDSGenerator ddsg, java.lang.String prefix)` Registers the parameter DynamicDSGenerator with the DataSource system.
    `static void` | `clearDynamicDSGenerators()` Removes all user-added DynamicDSGenerators from the system
    `DSResponse` | `execute(DSRequest req)` This method carries out the actual processing of a DataSource request.
    `DSResponse` | `executeAdd(DSRequest req)` This method is called by DataSource.execute() for "add" operations.
    `DSResponse` | `executeClientExport(DSRequest req)` This method is called by DataSource.execute() for "clientExport" operations.
    `DSResponse` | `executeCustom(DSRequest req)` This method is called by DataSource.execute() for "custom" operations.
    `DSResponse` | `executeFetch(DSRequest req)` This method is called by DataSource.execute() for "fetch" operations.
    `DSResponse` | `executeFileSource(DSRequest req)` This method is called by DataSource.execute() for "fileSource" operations.
    `DSResponse` | `executeRemove(DSRequest req)` This method is called by DataSource.execute() for "remove" operations.
    `DSResponse` | `executeUpdate(DSRequest req)` This method is called by DataSource.execute() for "update" operations.
    `java.util.List` | `fetch(java.lang.Object criteria)` This convenience method is the equivalent of creating a DSRequest with an operationType of "fetch", calling setCriteria() on it, and then calling its execute() method.
    `java.util.List` | `fetch(java.lang.String key, java.lang.Object value)` This convenience method is the equivalent of creating a DSRequest with an operationType of "fetch", calling setCriteria() on it, and then calling its execute() method.
    `java.util.Map` | `fetchById(java.lang.Object id)` Returns the record whose primary key matches the supplied id, or null if no such record exists.
    `java.util.Map` | `fetchSingle(java.lang.Object criteria)` This convenience method is the equivalent of creating a DSRequest with an operationType of "fetch", calling setCriteria() on it, calling its execute() method, then obtaining just the first item of the results.
    `java.util.Map` | `fetchSingle(java.lang.String key, java.lang.Object value)` This convenience method is the equivalent of creating a DSRequest with an operationType of "fetch", calling setCriteria() on it, calling its execute() method, then obtaining just the first item of the results.
    `java.util.List` | `filter(java.lang.Object criteria)` This convenience method is the equivalent of creating a DSRequest with an operationType of "filter", calling setCriteria() on it, and then calling its execute() method.
    `java.util.List` | `filter(java.lang.String key, java.lang.Object value)` This convenience method is the equivalent of creating a DSRequest with an operationType of "filter", calling setCriteria() on it, and then calling its execute() method.
    `static DataSource` | `fromXML(org.w3c.dom.Document doc)` Instantiates a DataSource from an XML Document - the documentElement of this document is expected to contain the DataSource definition.
    `static DataSource` | `fromXML(org.w3c.dom.Document doc, DSRequest dsRequest)` Instantiates a DataSource from an XML Document, with optional context DSRequest - the documentElement of the XML document is expected to contain the DataSource definition.
    `static DataSource` | `fromXML(org.w3c.dom.Element elem)` Instantiates a DataSource from an XML Element
    `static DataSource` | `fromXML(org.w3c.dom.Element elem, DSRequest dsRequest)` Instantiates a DataSource from an XML Element, with optional context DSRequest
    `static DataSource` | `fromXML(java.io.Reader reader)` Instantiates a DataSource from XML using a Reader
    `static DataSource` | `fromXML(java.io.Reader reader, DSRequest dsRequest)` Instantiates a DataSource from XML using a Reader, with optional context DSRequest
    `static DataSource` | `fromXML(java.lang.String xml)` Instantiates a DataSource from a String of XML
    `static DataSource` | `fromXML(java.lang.String xml, DSRequest dsRequest)` Instantiates a DataSource from a String of XML, with optional context DSRequest
    `java.lang.String` | `getAuditRevisionFieldName()` Get the field name for the audit revision field configured for this `DataSource`
    `java.lang.String` | `getAuditTimestampFieldName()` Get the field name for the audit timestamp field configured for this `DataSource`
    `java.lang.String` | `getAuditTypeFieldName()` Get the field name for the audit type field configured for this `DataSource`
    `java.lang.String` | `getAuditUserFieldName()` Get the field name for the audit user field configured for this `DataSource`
    `static DynamicDSGenerator` | `getDefaultDynamicDSGenerator()` Returns the default DynamicDSGenerator, or null if there is none
    `static java.util.Map` | `getDynamicDSGenerators()` Returns the non-default DynamicDSGenerators (ie, those that were registered against a startsWith string or a regular expression)
    `java.lang.String` | `getEnumConstantProperty()` Returns the name of the property this DataSource uses for constant name when translating enumerated types.
    `java.lang.String` | `getEnumOrdinalProperty()` Returns the name of the property this DataSource uses for ordinal number when translating enumerated types.
    `java.lang.String` | `getEnumTranslateStrategy()` Returns the strategy this DataSource uses for translating Java enumerated types (enums).
    `DSField` | `getField(java.lang.String fieldName)` Returns the field definition for the specified field.
    `java.util.List` | `getFieldNames()` Returns the list of field names in the DataSource as a List of strings.
    `java.io.Reader` | `getFile(DSFileSpec fileSpec)` Gets the contents of a file stored in this DataSource.
    `java.io.InputStream` | `getFileAsInputStream(DSFileSpec fileSpec)` Gets the contents of a file stored in this DataSource
    `java.lang.String` | `getFileAsString(DSFileSpec fileSpec)` Gets the contents of a file stored in this DataSource
    `java.lang.String` | `getFileContentsField()` Get the field name for the fileContents field configured for this DataSource for fileSource operations.
    `java.lang.String` | `getFileFormatField()` Get the field name for the fileFormat field configured for this DataSource for fileSource operations.
    `java.lang.String` | `getFileNameField()` Get the field name for the fileName field configured for this DataSource for fileSource operations.
    `java.lang.String` | `getFileTypeField()` Get the field name for the fileType field configured for this DataSource for fileSource operations.
    `java.util.List` | `getListProperties(java.util.List list)` Takes a List of beans/Elements/Maps and for all fields on this DataSource that specify a valueXPath, applies the xpath to each object in the List using the Jakarta JXPath library.
    `java.util.List` | `getListProperties(java.util.List list, boolean dropExtraFields, boolean dropIgnoredFields)` Takes a List of beans/Elements/Maps and for all fields on this DataSource that specify a valueXPath, applies the xpath to each object in the List using the Jakarta JXPath library.
    `java.lang.String` | `getPrimaryKey()` Returns the name of the primary key field.
    `java.util.Map` | `getProperties(java.lang.Object obj)` Takes a bean/Element/Map and for all fields on this DataSource that specify a valueXPath, applies the xpath to the object using the Jakarta JXPath library.
    `java.util.Map` | `getProperties(java.lang.Object obj, boolean dropExtraFields, boolean dropIgnoredFields)` Takes a bean/Element/Map and for all fields on this DataSource that specify a valueXPath, applies the xpath to the object using the Jakarta JXPath library.
    `java.util.Map` | `getProperties(java.lang.Object obj, java.util.Collection propsToKeep)` Takes a bean/Element/Map and for all fields on this DataSource that specify a valueXPath, applies the xpath to the object using the Jakarta JXPath library.
    `java.lang.Class` | `getPropertyJavaClass(java.lang.String propertyName, DSField field, java.lang.Object value)` Override point to allow subclasses to dynamically determine the Java class to use for a given property.
    `java.lang.String` | `getRecordXPath()` For an XML DataSource, returns the XPath expression used to retrieve the set of XML elements that constitute the records of this DataSource.
    `java.lang.Object` | `getTransactionObject(DSRequest req)` Returns an object that can be used to manage transactions for this DataSource and other DataSources of the same type and provider.
    `static java.lang.Object` | `getTransactionObject(DSRequest req, java.lang.String transactionObjectKey, java.lang.String shortTransactionObjectKey)` Helper method retrieves connection/transaction object for specified type of data source implementation or `null`.
    `boolean` | `hasFile(DSFileSpec fileSpec)` Indicates whether a file exists in this DataSource.
    `boolean` | `hasRecord(java.util.Map criteria)` Returns true if the dataSource contains at least one record that matches the supplied criteria
    `boolean` | `hasRecord(java.lang.String columnName, java.lang.Object value)` Returns true if the dataSource contains at least one record where the columnName matches the value.
    `protected void` | `initialized()` This method is called after the DataSource has been initialized allowing further custom initialization.
    `static boolean` | `isModificationOperation(java.lang.String operationType)` Convenience method that returns true for operations that modify data and false for those that do not.
    `boolean` | `isServerOnly()` Returns true if this datasource has been declared with an attribute of "serverOnly=true".
    `java.util.List` | `listFiles(java.lang.Object criteria)` Get a list of files from the DataSource.
    `java.util.List` | `listFiles(java.lang.String type, java.lang.String format)` Get a list of files from the DataSource.
    `long` | `remove(java.lang.Object criteria)` This convenience method is the equivalent of creating a DSRequest with an operationType of "remove", calling setCriteria() on it, and then calling its execute() method.
    `static DynamicDSGenerator` | `removeDynamicDSGenerator()` Unregisters the current default DynamicDSGenerator (ie, the one at the top of the stack).
    `static DynamicDSGenerator` | `removeDynamicDSGenerator(java.util.regex.Pattern regex)` Removes the DynamicDSGenerator registered against the parameter regexp Pattern
    `static DynamicDSGenerator` | `removeDynamicDSGenerator(java.lang.String prefix)` Removes the DynamicDSGenerator registered against the parameter prefix String
    `java.util.List` | `removeFile(DSFileSpec fileSpec)` Remove a file stored in this DataSource.
    `java.util.List` | `renameFile(DSFileSpec oldSpec, DSFileSpec newSpec)` Rename a file stored in this DataSource.
    `java.util.Map` | `saveFile(DSFileSpec fileSpec, java.lang.Object contents)` Save a file to the DataSource.
    `void` | `setEnumConstantProperty(java.lang.String newValue)` Sets the name of the property this DataSource should use for constant name when translating enumerated types.
    `void` | `setEnumOrdinalProperty(java.lang.String newValue)` Sets the name of the property this DataSource should use for ordinal number when translating enumerated types.
    `void` | `setEnumTranslateStrategy(java.lang.String newValue)` Sets the strategy this DataSource uses to translate enumerated types (objects of type enum).
    `java.lang.Object` | `setProperties(java.util.Map properties, java.lang.Object target)` Applies all properties in a Map to a target bean by calling setter methods according to the Java Beans naming convention ("name" -> setName()), including recursive traversal of sub-beans and JXPath-based setting of properties in nested beans.
    `void` | `transformMultipleFields(DSRequest req)` Transforms the values for fields declared multiple:true in the incoming DSRequest.
    `void` | `transformMultipleFields(DSResponse res)` Transforms the values for fields declared multiple:true in a DSResponse.
    `long` | `update(java.lang.Object criteria, java.lang.Object values)` This convenience method is the equivalent of creating a DSRequest with an operationType of "update", calling setValues() and setCriteria() on it, and then calling its execute() method.
    `ErrorReport` | `validate(java.util.Map data, boolean reportMissingRequiredFields)` Takes a Map of fieldName -> value (data argument) and validates the data using the validators specified on this dataSource.

    - ### Methods inherited from interface com.isomorphic.js.IToJSON

      `toJSON`

- - ### Field Detail

    - #### inInitState

          protected static final java.util.Map inInitState

      Holds data sources which are in init state.

    - #### OP_FETCH

          public static final java.lang.String OP_FETCH

      Constant specifying the fetch operation. The fetch operation typically provides a set of criteria and expects a set of records as a response.
      See Also:
        Constant Field Values

    - #### OP_ADD

          public static final java.lang.String OP_ADD

      Constant specifying the add operation. The add operation is a request to add a set of records to a whatever backing store is used as the datasource.
      See Also:
        Constant Field Values

    - #### OP_REMOVE

          public static final java.lang.String OP_REMOVE

      Constant specifying the remove operation. The remove operation is a request to remove a set of records from whatever backing store is used as the datasource.
      See Also:
        Constant Field Values

    - #### OP_UPDATE

          public static final java.lang.String OP_UPDATE

      Constant specifying the update operation. The update operation typically provides a set of criteria and new values for certain fields and expects that records matching the provided criteria will be updated with the new values.
      See Also:
        Constant Field Values

    - #### OP_CUSTOM

          public static final java.lang.String OP_CUSTOM

      Constant specifying a custom operation. SmartClient components do not send operations of this type. It is reserved for programmatic use.
      See Also:
        Constant Field Values

    - #### OP_VALIDATE

          public static final java.lang.String OP_VALIDATE

      Constant specifying the validate operation.
      See Also:
        Constant Field Values

    - #### OP_CLIENT_EXPORT

          public static final java.lang.String OP_CLIENT_EXPORT

      Constant specifying a clientExport operation. DataBoundComponents send operations of this type when they are bound to a DataSource with a "clientExport" OperationBinding that is named in the call to exportClientData(). These operations can also be sent programmatically, by calling exportClientData() directly on the DataSource, naming the OperationBinding as described above.
      See Also:
        Constant Field Values

    - #### OP_GET_FILE

          public static final java.lang.String OP_GET_FILE

      Constant specifying a getFile operation.
      See Also:
        Constant Field Values

    - #### OP_HAS_FILE

          public static final java.lang.String OP_HAS_FILE

      Constant specifying a hasFile operation.
      See Also:
        Constant Field Values

    - #### OP_LIST_FILES

          public static final java.lang.String OP_LIST_FILES

      Constant specifying a listFiles operation.
      See Also:
        Constant Field Values

    - #### OP_SAVE_FILE

          public static final java.lang.String OP_SAVE_FILE

      Constant specifying a saveFile operation.
      See Also:
        Constant Field Values

    - #### OP_RENAME_FILE

          public static final java.lang.String OP_RENAME_FILE

      Constant specifying a renameFile operation.
      See Also:
        Constant Field Values

    - #### OP_REMOVE_FILE

          public static final java.lang.String OP_REMOVE_FILE

      Constant specifying a removeFile operation.
      See Also:
        Constant Field Values

    - #### OP_FILE_SOURCE

          public static final java.util.Set OP_FILE_SOURCE

      Constant specifying the fileSource operations.

  - ### Method Detail

    - #### addDynamicDSGenerator

          public static void addDynamicDSGenerator(DynamicDSGenerator ddsg)

      Registers the parameter DynamicDSGenerator with the DataSource system by placing it at the top of a stack of DynamicDSGenerators. Whenever the system needs a DataSource in future, it will first call the `DynamicDSGenerator.getDataSource(String, DSRequest)` method of the DynamicDSGenerator. If that returns `null`, it will proceed to call the same method on any other DynamicDSGenerators in the stack, in reverse order of their registration (the normal LIFO ordering of a stack). Only if all the registered DynamicDSGenerators return null does the framework revert to the normal system of obtaining a DataSource instance.

      NOTE:

      - If you use this API, your DynamicDSGenerator will be called for every DataSource that the framework needs, including the very large number of internal usages. You probably don't want this - see `DataSource.addDynamicDSGenerator(DynamicDSGenerator, String)` and `DataSource.addDynamicDSGenerator(DynamicDSGenerator, Pattern)` for APIs that are more likely to be suitable
      - If you use this API anyway, you must be certain to return `null` for DataSources that you cannot provide an instance of
      Parameters:
        `ddsg` - A DynamicDSGenerator to register as the new default
      See Also:
        `DataSource.removeDynamicDSGenerator()`

    - #### removeDynamicDSGenerator

          public static DynamicDSGenerator removeDynamicDSGenerator()

      Unregisters the current default DynamicDSGenerator (ie, the one at the top of the stack). Does nothing if there is no current default (ie, if the stack is empty).

      If there are other default DynamicDSGenerators on the stack (because `DataSource.addDynamicDSGenerator(DynamicDSGenerator)` has been called more than once), the next one in the stack becomes the current default. Otherwise, there is no default DynamicDSGenerator and the framework will fall back to using the normal system for obtaining DataSource instances.

      Note, this API applies only to the stack of default DynamicDSGenerators - ie, those that were not registered against a prefix string or regular expression. It is quite possible to remove the last default DynamicDSGenerator and still have all of your DataSources generated dynamically via the prefix- or regex-based generators. See `DataSource.addDynamicDSGenerator(DynamicDSGenerator, String)` and `DataSource.addDynamicDSGenerator(DynamicDSGenerator, Pattern)`

      Returns:
        the DynamicDSGenerator we just removed, or null
      See Also:
        `DataSource#addDynamicDSGenerator()`

    - #### addDynamicDSGenerator

          public static void addDynamicDSGenerator(DynamicDSGenerator ddsg,
                                   java.lang.String prefix)

      Registers the parameter DynamicDSGenerator with the DataSource system. The DynamicDSGenerator will only be called for for DataSource ID's which start with the parameter prefix.

      You can add multiple DynamicDSGenerators using this API. If two or more are registered with prefixes that match a given DataSource ID, the one added first wins. Eg, if you have prefixes "c" and "cust" registered, then the "customer" DataSource will be provided by whichever of those two DynamicDSGenerators was registered first. Note that this "earliest first" basis also applies to DynamicDSGenerators registered with a regexp; if you had a DataSource ID that matched both a prefix and a regexp, whichever one of the two registrations came first would be used - there is no priority given to one or the other styles of ID matching.

      Parameters:
        `ddsg` - A DynamicDSGenerator to register as the default
        `prefix` - A prefix String as described above

    - #### addDynamicDSGenerator

          public static void addDynamicDSGenerator(DynamicDSGenerator ddsg,
                                   java.util.regex.Pattern regex)

      Registers the parameter DynamicDSGenerator with the DataSource system. The DynamicDSGenerator will only be called for for DataSource ID's which match the regexp provided in the parameter `java.util.regex.Pattern`

      You can add multiple DynamicDSGenerators using this API. If two or more are registered with regular expressions that match a given DataSource ID, the one added first wins. This also applies to DynamicDSGenerators registered with a simple prefix String.

      Parameters:
        `ddsg` - A DynamicDSGenerator to register as the default
        `regex` - A Pattern representing a regular expression to match against incoming DataSource IDs

    - #### getDefaultDynamicDSGenerator

          public static DynamicDSGenerator getDefaultDynamicDSGenerator()

      Returns the default DynamicDSGenerator, or null if there is none
      Returns:
        The default DynamicDSGenerator

    - #### getDynamicDSGenerators

          public static java.util.Map getDynamicDSGenerators()

      Returns the non-default DynamicDSGenerators (ie, those that were registered against a startsWith string or a regular expression)
      Returns:
        A map of the non-default DynamicDSGenerators, keyed by the startsWith string or regexp

    - #### removeDynamicDSGenerator

          public static DynamicDSGenerator removeDynamicDSGenerator(java.lang.String prefix)

      Removes the DynamicDSGenerator registered against the parameter prefix String
      Returns:
        The DynamicDSGenerator we just removed

    - #### removeDynamicDSGenerator

          public static DynamicDSGenerator removeDynamicDSGenerator(java.util.regex.Pattern regex)

      Removes the DynamicDSGenerator registered against the parameter regexp Pattern
      Returns:
        The DynamicDSGenerator we just removed

    - #### clearDynamicDSGenerators

          public static void clearDynamicDSGenerators()

      Removes all user-added DynamicDSGenerators from the system

    - #### initialized

          protected void initialized()
                              throws java.lang.Exception

      This method is called after the DataSource has been initialized allowing further custom initialization.

      The default implementation does nothing.

      Throws:
        `java.lang.Exception` - if an error occurs during initialization

    - #### fromXML

          public static DataSource fromXML(org.w3c.dom.Element elem)
                                    throws java.lang.Exception

      Instantiates a DataSource from an XML Element
      Parameters:
        `elem` - XML Element containing the DataSource definition
      Returns:
        an instance of DataSource
      Throws:
        `java.lang.Exception` - if an error occurs during DataSource instantiation

    - #### fromXML

          public static DataSource fromXML(org.w3c.dom.Element elem,
                           DSRequest dsRequest)
                                    throws java.lang.Exception

      Instantiates a DataSource from an XML Element, with optional context DSRequest
      Parameters:
        `elem` - XML Element containing the DataSource definition
        `dsRequest` - DSRequest to use as a context object if the creation of this DataSource involves the automatic creation of further, possibly user-generated, DataSources (eg, if this DataSource inheritsFrom a user-generated one)
      Returns:
        an instance of DataSource
      Throws:
        `java.lang.Exception` - if an error occurs during DataSource instantiation

    - #### fromXML

          public static DataSource fromXML(org.w3c.dom.Document doc)
                                    throws java.lang.Exception

      Instantiates a DataSource from an XML Document - the documentElement of this document is expected to contain the DataSource definition.
      Parameters:
        `doc` - XML Document containing the DataSource definition
      Returns:
        an instance of DataSource
      Throws:
        `java.lang.Exception` - if an error occurs during DataSource instantiation

    - #### fromXML

          public static DataSource fromXML(org.w3c.dom.Document doc,
                           DSRequest dsRequest)
                                    throws java.lang.Exception

      Instantiates a DataSource from an XML Document, with optional context DSRequest - the documentElement of the XML document is expected to contain the DataSource definition.
      Parameters:
        `doc` - XML Document containing the DataSource definition
        `dsRequest` - DSRequest to use as a context object if the creation of this DataSource involves the automatic creation of further, possibly user-generated, DataSources (eg, if this DataSource inheritsFrom a user-generated one)
      Returns:
        an instance of DataSource
      Throws:
        `java.lang.Exception` - if an error occurs during DataSource instantiation

    - #### fromXML

          public static DataSource fromXML(java.lang.String xml)
                                    throws java.lang.Exception

      Instantiates a DataSource from a String of XML
      Parameters:
        `xml` - XML string containing the DataSource definition
      Returns:
        an instance of DataSource
      Throws:
        `java.lang.Exception` - if an error occurs during DataSource instantiation

    - #### fromXML

          public static DataSource fromXML(java.lang.String xml,
                           DSRequest dsRequest)
                                    throws java.lang.Exception

      Instantiates a DataSource from a String of XML, with optional context DSRequest
      Parameters:
        `xml` - XML string containing the DataSource definition
        `dsRequest` - DSRequest to use as a context object if the creation of this DataSource involves the automatic creation of further, possibly user-generated, DataSources (eg, if this DataSource inheritsFrom a user-generated one)
      Returns:
        an instance of DataSource
      Throws:
        `java.lang.Exception` - if an error occurs during DataSource instantiation

    - #### fromXML

          public static DataSource fromXML(java.io.Reader reader)
                                    throws java.lang.Exception

      Instantiates a DataSource from XML using a Reader
      Parameters:
        `reader` - Reader supplying XML containing the DataSource definition
      Returns:
        an instance of DataSource
      Throws:
        `java.lang.Exception` - if an error occurs during DataSource instantiation

    - #### fromXML

          public static DataSource fromXML(java.io.Reader reader,
                           DSRequest dsRequest)
                                    throws java.lang.Exception

      Instantiates a DataSource from XML using a Reader, with optional context DSRequest
      Parameters:
        `reader` - Reader supplying XML containing the DataSource definition
        `dsRequest` - DSRequest to use as a context object if the creation of this DataSource involves the automatic creation of further, possibly user-generated, DataSources (eg, if this DataSource inheritsFrom a user-generated one)
      Returns:
        an instance of DataSource
      Throws:
        `java.lang.Exception` - if an error occurs during DataSource instantiation

    - #### getFieldNames

          public java.util.List getFieldNames()

      Returns the list of field names in the DataSource as a List of strings.
      Returns:
        the list of field names in the DataSource as a List of strings

    - #### getPrimaryKey

          public java.lang.String getPrimaryKey()

      Returns the name of the primary key field. Avoid this method for DataSources with composite keys (ie, multiple primaryKey fields): it simply returns the first key field it finds, which will rarely be useful for a composite key.
      Returns:
        the name of the primary key field

    - #### getField

          public DSField getField(java.lang.String fieldName)

      Returns the field definition for the specified field.
      Parameters:
        `fieldName` - the name of the field whose definition you want
      Returns:
        the field definition for the specified field
      See Also:
        `DSField`

    - #### getRecordXPath

          public java.lang.String getRecordXPath()

      For an XML DataSource, returns the XPath expression used to retrieve the set of XML elements that constitute the records of this DataSource.

      For example, an "ItemSearch" might return metadata along with the set of `<Item>` elements that one might want to display in a grid. The XPath expression to retrieve just the `<Item>` elements in this case might be "//Item", which would select all `<Item>` elements anywhere in the returned document.

      Returns:
        the XPath expression

    - #### isModificationOperation

          public static boolean isModificationOperation(java.lang.String operationType)

      Convenience method that returns true for operations that modify data and false for those that do not.
      Returns:
        true if operationType is one of "add", "remove" or "update" and false otherwise.

    - #### transformMultipleFields

          public void transformMultipleFields(DSRequest req)

      Transforms the values for fields declared multiple:true in the incoming DSRequest.

      See client-side docs for DataSourceField.multipleStorage for possible behaviors. This transformation is performed in DataSource.execute(), before operationType-specific methods like executeFetch or executeUpdate() are called.

      Parameters:
        `req` - the request to be transformed.

    - #### transformMultipleFields

          public void transformMultipleFields(DSResponse res)

      Transforms the values for fields declared multiple:true in a DSResponse.

      See client-side docs for DataSourceField.multipleStorage for possible behaviors. This transformation is performed in DataSource.execute(), after operationType-specific methods like executeFetch or executeUpdate() are called.

      Parameters:
        `res` - the DSResponse to be transformed.

    - #### execute

          public DSResponse execute(DSRequest req)
                             throws java.lang.Exception

      This method carries out the actual processing of a DataSource request. It can be overridden to provide centralized logic that applies to all operation types (such as transaction management, for example), or to implement special validation rules that cannot be handled by the built-in validation system. Generally, however, it is more appropriate to override the method specific to the operationType - executeFetch(), executeRemove(), executeAdd(), executeUpdate() or executeCustom(). Note that you must call the validate() method to retain correct validation behavior if you override this method and do not invoke super() This method is also the place where the transform happens if dataSourceField.multipleStorage is used. The transform is performed by two metods, `com.isomorphic.datasource.DataSource.transformMultipleFields(DSRequest)` and `com.isomorphic.datasource.DataSource.transformMultipleFields(DSResponse)`.
      Parameters:
        `req` - The DSRequest object representing this operation
      Returns:
        A valid DSResponse
      Throws:
        `java.lang.Exception`

    - #### getAuditTypeFieldName

          public java.lang.String getAuditTypeFieldName()

      Get the field name for the audit type field configured for this `DataSource`
      Returns:
        the field name representing the type field configured for the audit `DataSource`.

    - #### getAuditRevisionFieldName

          public java.lang.String getAuditRevisionFieldName()

      Get the field name for the audit revision field configured for this `DataSource`
      Returns:
        the field name representing the revision field configured for the audit `DataSource`.

    - #### getAuditTimestampFieldName

          public java.lang.String getAuditTimestampFieldName()

      Get the field name for the audit timestamp field configured for this `DataSource`
      Returns:
        the field name representing the timestamp field configured for the audit `DataSource`.

    - #### getAuditUserFieldName

          public java.lang.String getAuditUserFieldName()

      Get the field name for the audit user field configured for this `DataSource`
      Returns:
        the field name representing the user field configured for the audit `DataSource`.

    - #### setProperties

          public java.lang.Object setProperties(java.util.Map properties,
                                       java.lang.Object target)

      Applies all properties in a Map to a target bean by calling setter methods according to the Java Beans naming convention ("name" -> setName()), including recursive traversal of sub-beans and JXPath-based setting of properties in nested beans.

      When DataSourceField.valueXPath is set, the valueXPath is treated as a Jakarta JXPath expression. If some intervening objects in a JXPath are `nulls`, this method attempts to create missing objects if possible - see `com.isomorphic.util.JXPathContextObjectFactory` documentation for details.

      Entries in the "properties" Map where there is no same-named DataSource field are discarded.

      This method can be used to recursively populate an object graph of Beans and Collections, using multiple DataSources to define rules for how subobjects are populated. Specifically, if the "properties" Map has entries whose values are Maps, if the corresponding field on the DataSource is declared as being of a DataSource type (ie, the type property is set to the ID of some valid DataSource), these properties will be applied via a recursive call to DataSource.setProperties() using the indicated DataSource. This will also occur for a Collection within the "properties" Map if the target bean has a corresponding property of Collection type.

      When the type to use is ambiguous (for example, a property on the target bean is declared as a base type with many sub-types, or is an abstract type like List) the DataSourceField properties javaClass, javaCollectionClass and javaKeyClass can be used to specify a concrete type - see the client-side reference docs for further details.

      Ultimately, this method calls `DataTools.setProperties(Map, Object, DataSource)` - see the documentation of these method for details of treatment of object vs primitive type, Java Generics, Enums, and other cases.

      Parameters:
        `properties` - Map of DataSource fieldName -> value
        `target` - Target object to which the values are to be applied

    - #### getListProperties

          public java.util.List getListProperties(java.util.List list)

      Takes a List of beans/Elements/Maps and for all fields on this DataSource that specify a valueXPath, applies the xpath to each object in the List using the Jakarta JXPath library. If no valueXPath is specified, this method attempts to treat each object in the List as a bean for that value. Values specified for fieldNames that are not declared in the datasource on which this method is being called are discarded.
      Parameters:
        `list` - The List of objects that is mined for values.
      Returns:
        A List of Maps of fieldNames -> fieldValues derived as described above.

    - #### getListProperties

          public java.util.List getListProperties(java.util.List list,
                                         boolean dropExtraFields,
                                         boolean dropIgnoredFields)

      Takes a List of beans/Elements/Maps and for all fields on this DataSource that specify a valueXPath, applies the xpath to each object in the List using the Jakarta JXPath library. If no valueXPath is specified, this method attempts to treat each object in the List as a bean for that value. The `dropExtraFields` parameter controls whether or not values specified for fieldNames that are not declared in the datasource on which this method is being called are discarded.
      Parameters:
        `list` - The List of objects that is mined for values.
        `dropExtraFields` - If true, values specified for fieldNames that are not declared in the datasource on which this method is being called are discarded, otherwise they are kept.
        `dropIgnoredFields` - If true, values specified for fieldNames that are declared in the datasource on which this method is being called with the property ignore: true are are discarded; otherwise they are kept
      Returns:
        A List of Maps of fieldNames -> fieldValues derived as described above.

    - #### getProperties

          public java.util.Map getProperties(java.lang.Object obj)

      Takes a bean/Element/Map and for all fields on this DataSource that specify a valueXPath, applies the xpath to the object using the Jakarta JXPath library. If no valueXPath is specified, this method attempts to treat the target as a bean for that value. Values specified for fieldNames that are not declared in the datasource on which this method is being called are discarded.
      Parameters:
        `obj` - The object that is mined for values.
      Returns:
        A map of fieldNames -> fieldValues derived as described above.

    - #### getProperties

          public java.util.Map getProperties(java.lang.Object obj,
                                    boolean dropExtraFields,
                                    boolean dropIgnoredFields)

      Takes a bean/Element/Map and for all fields on this DataSource that specify a valueXPath, applies the xpath to the object using the Jakarta JXPath library. If no valueXPath is specified, this method attempts to treat the target as a bean for that value. The `dropExtraFields` parameter controls whether or not values specified for fieldNames that are not declared in the datasource on which this method is being called are discarded.
      Parameters:
        `obj` - The object that is mined for values.
        `dropExtraFields` - If true, values specified for fieldNames that are not declared in the datasource on which this method is being called are discarded, otherwise they are kept.
        `dropIgnoredFields` - If true, values specified for fieldNames that are declared in the datasource on which this method is being called with the property ignore: true are are discarded; otherwise they are kept
      Returns:
        A map of fieldNames -> fieldValues derived as described above.

    - #### getProperties

          public java.util.Map getProperties(java.lang.Object obj,
                                    java.util.Collection propsToKeep)

      Takes a bean/Element/Map and for all fields on this DataSource that specify a valueXPath, applies the xpath to the object using the Jakarta JXPath library. If no valueXPath is specified, this method attempts to treat the target as a bean for that value.
      Parameters:
        `obj` - The object that is mined for values.
        `propsToKeep` - specifies an explicit list of properties to retain the datasource on which this method is being called are discarded, otherwise they are kept.
      Returns:
        A map of fieldNames -> fieldValues derived as described above.

    - #### validate

          public ErrorReport validate(java.util.Map data,
                             boolean reportMissingRequiredFields)
                               throws java.lang.Exception

      Takes a Map of fieldName -> value (data argument) and validates the data using the validators specified on this dataSource.
      Parameters:
        `data` - Map of DataSource fieldName -> value
        `reportMissingRequiredFields` - for operations like update or fetch/filter only partial fields may be specified by the user. In those cases you want to ignore missing required fields.
      Returns:
        ErrorReport or null if there were no errors.
      Throws:
        `java.lang.Exception` - if an exception occurs during validation

    - #### executeFetch

          public DSResponse executeFetch(DSRequest req)
                                  throws java.lang.Exception

      This method is called by DataSource.execute() for "fetch" operations. It is the appropriate override point if you wish to provide custom handling of a "fetch".
      Parameters:
        `req` - The DSRequest object representing this operation
      Returns:
        A valid DSResponse
      Throws:
        `java.lang.Exception`

    - #### executeRemove

          public DSResponse executeRemove(DSRequest req)
                                   throws java.lang.Exception

      This method is called by DataSource.execute() for "remove" operations. It is the appropriate override point if you wish to provide custom handling of a "remove".
      Parameters:
        `req` - The DSRequest object representing this operation
      Returns:
        A valid DSResponse
      Throws:
        `java.lang.Exception`

    - #### executeAdd

          public DSResponse executeAdd(DSRequest req)
                                throws java.lang.Exception

      This method is called by DataSource.execute() for "add" operations. It is the appropriate override point if you wish to provide custom handling of an "add".
      Parameters:
        `req` - The DSRequest object representing this operation
      Returns:
        A valid DSResponse
      Throws:
        `java.lang.Exception`

    - #### executeUpdate

          public DSResponse executeUpdate(DSRequest req)
                                   throws java.lang.Exception

      This method is called by DataSource.execute() for "update" operations. It is the appropriate override point if you wish to provide custom handling of an "update".
      Parameters:
        `req` - The DSRequest object representing this operation
      Returns:
        A valid DSResponse
      Throws:
        `java.lang.Exception`

    - #### executeCustom

          public DSResponse executeCustom(DSRequest req)
                                   throws java.lang.Exception

      This method is called by DataSource.execute() for "custom" operations. It is the appropriate override point to provide logic for handling a "custom" operation.
      Parameters:
        `req` - The DSRequest object representing this operation
      Returns:
        A valid DSResponse
      Throws:
        `java.lang.Exception`

    - #### executeClientExport

          public DSResponse executeClientExport(DSRequest req)
                                         throws java.lang.Exception

      This method is called by DataSource.execute() for "clientExport" operations. It is the appropriate override point to provide logic for handling a "clientExport" operation.
      Parameters:
        `req` - The DSRequest object representing this operation
      Returns:
        A valid DSResponse
      Throws:
        `java.lang.Exception`

    - #### executeFileSource

          public DSResponse executeFileSource(DSRequest req)
                                       throws java.lang.Exception

      This method is called by DataSource.execute() for "fileSource" operations. It is the appropriate override point to provide logic for handling a "fileSource" operation.

      The actual operation to be performed is indicated by the request's `operationType`. The `operationType` may be one of the following:

      getFile, hasFile, listFiles
        Return a `DSResponse` appropriate for a "fetch" operation, using the fileName, fileType and fileFormat (or other criteria) provided by the `DSRequest`. Only include the fileContents in the outputs for the "getFile" operationId.
      saveFile
        Return a DSResponse appropriate for an "add" operation, using the fileName, fileType, fileFormat and fileContents provided by the DSRequest. Do not include the fileContents in the outputs. Note that the actual operation may be implemented as an "add" or an "update", depending on whether the file exists already.
      renameFile
        Return a DSResponse appropriate for an "update" operation. The existing fileName, fileType and fileFormat are provided in the request's `oldValues`, since they may be primary keys (so that providing only the new values would not be sufficient).
      removeFile
        Return a DSResponse appropriate for a "remove" opration, using the fileName, fileType and fileFormat provided by the DSRequest.

      In each case, the fileName, fileType, fileFormat and fileContents are provided in the DSRequest using those field names. The default implementation uses `getFileNameField()`, `getFileTypeField()`, `getFileFormatField()` and `getFileContentsField()` to construct the appropriate sub-request to access the real fields of the DataSource.

      In constructing a DSResponse, you must use the field names fileName, fileType, fileFormat and fileContents rather than the real fields of the DataSource.

      The default implementation issues a sub-request of type "fetch", "add", "remove" or "update", with an operationId equal to the operationType provided here, and with field names translated according the DataSource configuration. Therefore, you can customize the sub-request operationTypes, by checking for the relevant operationId.

      Note that the "renameFile" operationId is implemented, by default, to perform an "update" operation, unless the fileNameField, fileFormatField or fileTypeField are primary keys. If one of those fields is a primary key, then "renameFile" is instead implemented as a "remove" followed by an "add", since there can be difficulties updating primary keys.

      Parameters:
        `req` - The DSRequest object representing this operation.
      Returns:
        A valid DSResponse, constructed as explained above.
      Throws:
        `java.lang.Exception`

    - #### getFileNameField

          public java.lang.String getFileNameField()

      Get the field name for the fileName field configured for this DataSource for fileSource operations.

      This allows fileSource operations to always use "fileName" as a field name, no matter where this DataSource stores the fileName.

      The default implementation works as follows:

      - If the DataSource configuration specifies a "fileNameField", then that is used.
      - Otherwise, if there is a field named "fileName", "name", or "title", then that field is used.
      - Otherwise, if there is a single primary key, and it has the type "text", then that field is used.
      - Otherwise, an error is logged
      Returns:
        The name of the fileNameField

    - #### getFileContentsField

          public java.lang.String getFileContentsField()

      Get the field name for the fileContents field configured for this DataSource for fileSource operations. This allows fileSource operations to always use "fileContents" as a field name, no matter where this DataSource stores the fileContents. The default implementation first checks for fileContentsField in the DataSource configuration. If not found, it checks for a field named fileContents or contents. If not found, it will use the longest text field which is not the `fileNameField`, `fileTypeField`, or `fileFormatField`.
      Returns:
        The name of the fileContentsField

    - #### getFileTypeField

          public java.lang.String getFileTypeField()

      Get the field name for the fileType field configured for this DataSource for fileSource operations. This allows fileSource operations to always use "fileType" as a field name, no matter where this DataSource stores the fileType. The default implementation will first look for a fileTypeField specified in the DataSource configuration. If not found, it will look for a field named "fileType". Otherwise, it is assumed that this DataSource does not distinguish between multiple fileTypes, so any supplied fileType is ignored by fileSource operations.
      Returns:
        The name of the fileTypeField

    - #### getFileFormatField

          public java.lang.String getFileFormatField()

      Get the field name for the fileFormat field configured for this DataSource for fileSource operations. This allows fileSource operations to always use "fileFormat" as a field name, no matter where this DataSource stores the fileFormat. The default implementation will first look for a fileFormatField specified in the DataSource configuration. If not found, it will look for a field named "fileFormat". Otherwise, it is assumed that this DataSource does not distinguish between multiple fileFormats, so any supplied fileFormat is ignored by fileSource operations.
      Returns:
        The name of the fileFormatField

    - #### getFile

          public java.io.Reader getFile(DSFileSpec fileSpec)
                                 throws java.lang.Exception

      Gets the contents of a file stored in this DataSource.
      Parameters:
        `fileSpec` - A specifier for the file.
      Returns:
        A Reader for the contents of the file. Null if the file is not found.
      Throws:
        `java.lang.Exception`

    - #### getFileAsString

          public java.lang.String getFileAsString(DSFileSpec fileSpec)
                                           throws java.lang.Exception

      Gets the contents of a file stored in this DataSource
      Parameters:
        `fileSpec` - A specifier for the file.
      Returns:
        The contents of the file. Null if the file is not found.
      Throws:
        `java.lang.Exception`

    - #### getFileAsInputStream

          public java.io.InputStream getFileAsInputStream(DSFileSpec fileSpec)
                                                   throws java.lang.Exception

      Gets the contents of a file stored in this DataSource
      Parameters:
        `fileSpec` - A specifier for the file.
      Returns:
        The contents of the file. Null if the file is not found.
      Throws:
        `java.lang.Exception`

    - #### hasFile

          public boolean hasFile(DSFileSpec fileSpec)
                          throws java.lang.Exception

      Indicates whether a file exists in this DataSource.
      Parameters:
        `fileSpec` - A specifier for the file.
      Returns:
        Whether the file can be found.
      Throws:
        `java.lang.Exception`

    - #### saveFile

          public java.util.Map saveFile(DSFileSpec fileSpec,
                               java.lang.Object contents)
                                 throws java.lang.Exception

      Save a file to the DataSource.
      Parameters:
        `fileSpec` - A specifier for the file. A fileName is always required. Some DataSources will require that the fileType and fileFormat be specified.
        `contents` - The contents of the file.
      Returns:
        A map with the saved record, but without the fileContents
      Throws:
        `java.lang.Exception`

    - #### listFiles

          public java.util.List listFiles(java.lang.Object criteria)
                                   throws java.lang.Exception

      Get a list of files from the DataSource.
      Parameters:
        `criteria` - Criteria to apply. References to `fileName`, `fileContents` and `fileType` will be translated to the native field names configured for this DataSource. Note that this parameter does not work with AdvancedCriteria yet.
      Returns:
        The FileList. The Maps will have the `fileName`, `fileType` and `fileFormat` fields populated, but not the `fileContents` field. (You can use `getFile()` to get the `fileContents`).
      Throws:
        `java.lang.Exception`

    - #### listFiles

          public java.util.List listFiles(java.lang.String type,
                                 java.lang.String format)
                                   throws java.lang.Exception

      Get a list of files from the DataSource.
      Parameters:
        `type` - The file type (e.g. "ds")
        `format` - The file format (e.g. "xml" or "js")
      Returns:
        The FileList. The Maps will have the `fileName`, `fileType` and `fileFormat` fields populated, but not the `fileContents` field. (You can use `getFile()` to get the `fileContents`).
      Throws:
        `java.lang.Exception`

    - #### renameFile

          public java.util.List renameFile(DSFileSpec oldSpec,
                                  DSFileSpec newSpec)
                                    throws java.lang.Exception

      Rename a file stored in this DataSource.
      Parameters:
        `oldSpec` - The original fileSpec.
        `newSpec` - The new fileSpec.
      Returns:
        Records represening the renamed file(s). The records will have their `fileName`, `fileType`, and `fileFormat` fields populated, but not the `fileContents` field.
      Throws:
        `java.lang.Exception`

    - #### removeFile

          public java.util.List removeFile(DSFileSpec fileSpec)
                                    throws java.lang.Exception

      Remove a file stored in this DataSource.
      Parameters:
        `fileSpec` - A specifier for the file.
      Returns:
        Records represening the removed file(s). The records will have their `fileName`, `fileType` and `fileFormat` fields populated, but not the `fileContents` field.
      Throws:
        `java.lang.Exception`

    - #### fetch

          public java.util.List fetch(java.lang.Object criteria)
                               throws java.lang.Exception

      This convenience method is the equivalent of creating a DSRequest with an operationType of "fetch", calling setCriteria() on it, and then calling its execute() method.
      Parameters:
        `criteria` - The criteria to use for the fetch operation
      Returns:
        `List` with retrieved data.
      Throws:
        `java.lang.Exception`

    - #### fetch

          public java.util.List fetch(java.lang.String key,
                             java.lang.Object value)
                               throws java.lang.Exception

      This convenience method is the equivalent of creating a DSRequest with an operationType of "fetch", calling setCriteria() on it, and then calling its execute() method. The criteria object is formed by building a single-key map from the key and value passed in.
      Parameters:
        `key` - The criterion key
        `value` - The criterion value
      Returns:
        `List` with retrieved data.
      Throws:
        `java.lang.Exception`

    - #### filter

          public java.util.List filter(java.lang.Object criteria)
                                throws java.lang.Exception

      This convenience method is the equivalent of creating a DSRequest with an operationType of "filter", calling setCriteria() on it, and then calling its execute() method.
      Parameters:
        `criteria` - The criteria to use for the filter operation
      Returns:
        `List` with retrieved data.
      Throws:
        `java.lang.Exception`

    - #### filter

          public java.util.List filter(java.lang.String key,
                              java.lang.Object value)
                                throws java.lang.Exception

      This convenience method is the equivalent of creating a DSRequest with an operationType of "filter", calling setCriteria() on it, and then calling its execute() method. The criteria object is formed by building a single-key map from the key and value passed in.
      Parameters:
        `key` - The criterion key
        `value` - The criterion value
      Returns:
        `List` with retrieved data.
      Throws:
        `java.lang.Exception`

    - #### add

          public long add(java.lang.Object values)
                   throws java.lang.Exception

      This convenience method is the equivalent of creating a DSRequest with an operationType of "add", calling setValues() on it, and then calling its execute() method.
      Parameters:
        `values` - The values to use for the add operation
      Returns:
        `long` number of affected rows.
      Throws:
        `java.lang.Exception`

    - #### update

          public long update(java.lang.Object criteria,
                    java.lang.Object values)
                      throws java.lang.Exception

      This convenience method is the equivalent of creating a DSRequest with an operationType of "update", calling setValues() and setCriteria() on it, and then calling its execute() method.
      Parameters:
        `criteria` - The criteria to use for the update operation
        `values` - The values to use for the update operation
      Returns:
        `long` number of affected rows.
      Throws:
        `java.lang.Exception`

    - #### remove

          public long remove(java.lang.Object criteria)
                      throws java.lang.Exception

      This convenience method is the equivalent of creating a DSRequest with an operationType of "remove", calling setCriteria() on it, and then calling its execute() method.
      Parameters:
        `criteria` - The criteria to use for the remove operation
      Returns:
        `long` number of affected rows.
      Throws:
        `java.lang.Exception`

    - #### fetchSingle

          public java.util.Map fetchSingle(java.lang.String key,
                                  java.lang.Object value)
                                    throws java.lang.Exception

      This convenience method is the equivalent of creating a DSRequest with an operationType of "fetch", calling setCriteria() on it, calling its execute() method, then obtaining just the first item of the results. The criteria object is formed by building a single-key map from the key and value passed in.

      Note that this method expects the specified criterion to result in a single result, and will throw an exception if the multiple records match the request.

      Parameters:
        `key` - The criterion key
        `value` - The criterion value
      Returns:
        `Map` of retrieved object properties.
      Throws:
        `java.lang.Exception`

    - #### fetchSingle

          public java.util.Map fetchSingle(java.lang.Object criteria)
                                    throws java.lang.Exception

      This convenience method is the equivalent of creating a DSRequest with an operationType of "fetch", calling setCriteria() on it, calling its execute() method, then obtaining just the first item of the results.

      Note that this method expects the specified criteria to result in a single result, and will throw an exception if the multiple records match the request.

      Parameters:
        `criteria` - The criteria to use for the fetch operation
      Returns:
        `Map` of retrieved object properties.
      Throws:
        `java.lang.Exception`

    - #### getTransactionObject

          public java.lang.Object getTransactionObject(DSRequest req)
                                                throws java.lang.Exception

      Returns an object that can be used to manage transactions for this DataSource and other DataSources of the same type and provider. The object returned is of a type specific to the type of DataSource

      This method is part of the Automatic Transactions feature, which is effective only in Power edition and above.

      Throws:
        `java.lang.Exception`

    - #### getTransactionObject

          public static java.lang.Object getTransactionObject(DSRequest req,
                                              java.lang.String transactionObjectKey,
                                              java.lang.String shortTransactionObjectKey)
                                                       throws java.lang.Exception

      Helper method retrieves connection/transaction object for specified type of data source implementation or `null`.
      - for `SQLDataSource`:`

             Connection conn = DataSource.getTransactionObject(req, SQLTransaction.CONNECTION_ATTR + dbName);

        ` where `dbName` is name of database as configured in server.properties file. Returned `conn` is instance of `java.sql.Connection` to specified data base.
      - for `HibernateDataSource`:`

             Transaction tx = DataSource.getTransactionObject(req, HibernateTransaction.TRANSACTION_ATTR);
             Session session = HibernateTransaction.getTransactionSession(tx);

        ` `session` and `tx` instances of hibernate session and transaction object used by `HibernateDataSource`.
      - for `JPADataSource`:`

             JPAConnectionHolder holder = DataSource.getTransactionObject(req, EMF.TRANSACTION_ATTR);

        ` `JPAConnectionHolder` instance contains references to entity manager and transaction object used by `JPADataSource` instances.

      Transaction is started by first execution of corresponding data source implementation. Following operations should retrieve transaction object and use it but should never commit/rollback. Overall commit/rollback will be issued by `RPCManager` and will be handled by data source object which started transaction.

      This method is part of the Automatic Transactions feature, which is effective only in Power edition and above.
      Parameters:
        `req` - `DSRequest`
        `transactionObjectKey` - `String` Name of transaction object key.
      Returns:
        `Object` containing connection/transaction. Actual type of instance depends on passed parameter `transactionObjectKey`. `null` is returned if specified request does not contain reference to `RPCManager` or specified object is not set.
      Throws:
        `java.lang.Exception` - if provided `DSRequest` is `null`.

    - #### hasRecord

          public boolean hasRecord(java.lang.String columnName,
                          java.lang.Object value)
                            throws java.lang.Exception

      Returns true if the dataSource contains at least one record where the columnName matches the value.
      Parameters:
        `columnName` - The columnName to use in the search criteria
        `value` - The value to look for in the search criteria
      Throws:
        `java.lang.Exception`

    - #### hasRecord

          public boolean hasRecord(java.util.Map criteria)
                            throws java.lang.Exception

      Returns true if the dataSource contains at least one record that matches the supplied criteria
      Parameters:
        `criteria` - A Map containing the search criteria
      Throws:
        `java.lang.Exception`

    - #### fetchById

          public java.util.Map fetchById(java.lang.Object id)
                                  throws java.lang.Exception

      Returns the record whose primary key matches the supplied id, or null if no such record exists. For a DataSource with a composite primary key, this method's behavior is dependent on the type of the "id" parameter:
      - If "id" is a Map, it is assumed to be criteria expressing the full primary key, and is passed directly to the underlying operation. If the full set of primary key values is correctly provided in the Map, this will return the single record whose composite primary key matches that set of values
      - If "id" is not a Map, it is assumed to be a single value to match against the DataSource's first primary key field. In this case, it returns the first record (if any) where the first defined primary key field matches the supplied id
      Parameters:
        `id` - The primary key value to match, or a set of primary key values in a Map
      Throws:
        `java.lang.Exception`

    - #### getEnumTranslateStrategy

          public java.lang.String getEnumTranslateStrategy()

      Returns the strategy this DataSource uses for translating Java enumerated types (enums). See `DataSource.setEnumTranslateStrategy(String)` for details of valid translate strategies
      Returns:
        A String containing the enum translate strategy

    - #### setEnumTranslateStrategy

          public void setEnumTranslateStrategy(java.lang.String newValue)

      Sets the strategy this DataSource uses to translate enumerated types (objects of type enum). Valid values are:
      "name" Translates to/from a String matching the constant name
      "string" Translates to/from a String matching the `enum.toString()`
      "ordinal" Translates to/from an integer matching the ordinal number of the constant within the enumeration
      "bean" Translates to/from a JS object containing one property for each property defined within the enum. The constant itself and the ordinal number are included in the JS object. By default they are called "_constant" and "_ordinal", but this can be overridden on both JSTranslater and DataSource with the enumOrdinalProperty and enumConstantProperty properties (which have setters named using normal bean semantics)
      Parameters:
        `newValue` - A String containing the new enum translate strategy

    - #### getEnumOrdinalProperty

          public java.lang.String getEnumOrdinalProperty()

      Returns the name of the property this DataSource uses for ordinal number when translating enumerated types. Defaults to "_ordinal"
      Returns:
        The ordinal property name

    - #### getEnumConstantProperty

          public java.lang.String getEnumConstantProperty()

      Returns the name of the property this DataSource uses for constant name when translating enumerated types. Defaults to "_constant"
      Returns:
        The constant value property name

    - #### setEnumOrdinalProperty

          public void setEnumOrdinalProperty(java.lang.String newValue)

      Sets the name of the property this DataSource should use for ordinal number when translating enumerated types.
      Parameters:
        `newValue` - The new ordinal property name

    - #### setEnumConstantProperty

          public void setEnumConstantProperty(java.lang.String newValue)

      Sets the name of the property this DataSource should use for constant name when translating enumerated types.
      Parameters:
        `newValue` - The new constant value property name

    - #### getPropertyJavaClass

          public java.lang.Class getPropertyJavaClass(java.lang.String propertyName,
                                             DSField field,
                                             java.lang.Object value)
                                               throws java.lang.Exception

      Override point to allow subclasses to dynamically determine the Java class to use for a given property. The default implementation returns the Class indicated by the passed-in DSField's "javaClass" property. Scan the client-side documentation for "javaClass" for details.

      Your overriding method is passed the name of the property we are trying to populate, the raw value we are going to use to populate it, and the DSField object associated with the property. It is envisaged that this will be sufficient context to dynamically decide on a Class to use. For example, if the raw Map passed in contains a given property, your code might decide to use Class B rather than the normal Class A.

      Note that whatever class you return from this method will be used as the parameter type for the corresponding setter on the bean we are populating. This means that this method (and indeed the declarative "javaClass" property) is only useful if your Javabean property type is a supertype of whatever class you return from this method. Examples of valid use cases would include things like your Javabean property is of an interface or abstract type, or of a general base type like Object.

      Parameters:
        `propertyName` - Name of the property we are trying to populate, for context
        `field` - The associated `DSField`
        `value` - The raw value we are trying to assign to this property. Note this will ordinarily be a Map or a List of Maps
      Returns:
        The Class to use for this property; return the result of calling super() to fall back to default behavior, or null to bypass custom bean Class derivation for this property (we will use Reflection to determine the type to use, as described in the client-side documentation for `DataSourceField.javaClass`)
      Throws:
        `java.lang.Exception`

    - #### isServerOnly

          public boolean isServerOnly()

      Returns true if this datasource has been declared with an attribute of "serverOnly=true". Otherwise false.
      Returns:
        true if this is a server-side only DataSource.