6.9 Data Sources

Tabular data sources provide table structured, cached data to the XMA application. Usually, many applications have to deal with some kind of data that won't change very often. Examples are lists of values where the end user may select one out of the list in a combo box. Some call these lists domains and many companies have their own software systems to manage these domains like SPARDAT's domain system.

Since these kinds of lists do change infrequently (as compared to regular business data), it would be a waste of resource to transfer them on every page from the XMA server to the client. Therefore, XMA provides a data source plugin that provides data in the form of tables at the XMA client and the server using a caching mechanism, see the following figure:


The XMA application has access to a table using the interface ITabularDataSource. This interface is able to return tables ( as ITabularData object ) if a valid table specification (to be explained later) is provided.

The red arrows in the figure above show a typical flow of control through the plugin if the XMA client requests a particular table:

  • After the client calls ITabularDataSource , the XMA client runtime looks up the client cache (see arrow [2]).

  • If it has been found in the client cache, it is returned, otherwise the XMA client runtime contacts the server runtime (see arrow [3]).

  • The server runtime first looks up its own in memory cache at the server [4].

  • If the table is not located in the server cache either, the XMA server runtime contacts the right ITableProvider which finally must provide the table data, see [5]. For some types of data sources, the providers are included in the XMA server runtime. A XMA project may provide additional providers in order to define their custom data sources.

Of course, in reality the lookup operation would stop at some point if the table is either found in the clients or servers cache and is not expired.

To successfully access a data source, the caller of ITabularDataSource must provide a data source specification which simply is a String. The specification must follow the following syntax (example):

type=rsc,name=at.spardat.myappl.countries
A comma separated list of attributes as key - value pairs. The attribute type is reserved and should be used to discriminate among different types of data sources. Depending on type, more attributes usually will be required. The following type is reserved:


The provider for this source type is served from within the XMA server runtime (see ResourceBundle data sources). There is no need to write custom code.

Tabular data sources are implemented using XMA's plugin concept. Therefore, before a particular table may be accessed, the implementation of the ITabularDataSource plug-in must be retrieved. Starting point at the XMA client is the XMASessionClient, which provides access to the PluginManager:

    PluginManager               piManager = yourSession.getPluginManager();
    ITabularDataSource          dataSourcePlugin = (ITabularDataSource) piManager.getPlugin (ITabularDataSource.class);
At the server-side of XMA, the PluginManager is a singleton within the web-application:
    PluginManager               piManager = PluginManagerServer.getInstance();
    ITabularDataSource          dataSourcePlugin = (ITabularDataSource) piManager.getPlugin (ITabularDataSource.class);
Once you have got an instance of the plugin, a table is accessed using the method
    ITabularData ITabularDataSource.getTable (String spec, XMASession session)
See also Specification of data sources. The ITabularData interface provides access to deliberately structured tables using row and columns indexes, where the cells of the tables are of type Atom.

If you know that the table is a domain-table, you may use the method

    ITabularDomData ITabularDataSource.getDomTable (String spec, XMASession session)

ITabularDomData

provides a more adequate interface for accessing domain values by key.

If in the GUI designer an XMA Combo is created, then a data source can be specified in the combo's properties. This combo box then is filled with the values from the specified data source. See XMA Combo

This is an utility class to access data sources. This class can be used to get long or short values of domain keys or to retrieved a complete domain. Usually this class is not needed, as the domain handling is done by widget models (XMA Combo). See its javadoc for details: Domain

A data source implementation based at the Java resource bundle mechanism is already offered by XMA. This is a convenient way to define a smaller set of domain values used for the XMA Combo. Such a data source is defined like this (also see ResourceBundleProviderServer):

type=rsc,bundle=at.spardat.myappl.server.domains.MyBundle
Note that the property file has to reside in a server side package of your application. Normally a package is chosen which is accessible from all XMA components. This is a package which is copied to the application's commonserver.jar file (see CommonServer.jar). An example how the actual property files reside in the package structure is shown below. The property files can be defined language dependent:
at.spardat.myappl.server.domains.MyBundle.properties
at.spardat.myappl.server.domains.MyBundle_de.properties
at.spardat.myappl.server.domains.MyBundle_en.properties

The property file itself is a comma separated value (CSV) file. Here an example for a property file which serves as domain and can be used as data source by the XMA Combo is listed:

 COLS  = COD_KEY,SHORT_VALUE,LONG_VALUE,VALID_FROM,VALID_TO
 10    = "y",   "y",       "yes",D20030101,D20030720
 20    = "n",   "n",       "no",D20030101,D20030719

It is possible to add additional columns, the VALID_FROM,VALID_TO columns do not need to have values.

As shown above the property files can be defined language dependent. Then the data source retrieves the values from the file which matches the JVM language setting of the XMA client (as user.language=en). By default the JVM takes the language setting from the operation system (if it is not defined otherwise). Although the language setting of the XMA client is used (which is transferred to the XMA server), the actual resolving of the right property file is done at the XMA server, where the property files are existing. The java.util.ResourceBundle mechanism resolves property files this way (see the official Java API documentation for details):

There might be cases where the server's default Locale cannot be controlled by the application. Therefore, when defining a data source property file, one should never rely at any default settings to get the right language. So, if the application regards some language as its default, it should always define two property files for one language. For example English is regarded as default:
at.spardat.myappl.server.domains.MyBundle.properties
at.spardat.myappl.server.domains.MyBundle_en.properties

This always ensures that, if the client requests English, it will get the English version and if it requests some other language, for which no property file is defined, then also the English version (serving as default) is retrieved. If you do not want to maintain two versions of the same file you can also extend your build script so that language files regarded as default are always copied to files without language extension.

If your application must provide tabular cached data that cannot be served from the predefined providers in XMATabularDataSourceServer you may define your custom providers by doing the following steps:

  1. Create a subclass ( X in the following) of XMATabularDataSourceServer

  2. Specify X as the server implementation class of the data source plugin, see: Configuration of the Data Source Plugin.

  3. Create a class implementing the interface ITableProvider , call it MyProvider in the following. The task of MyProvider is to query tables for a particular custom data source type from the origin data store. That might be a database or some other back end legacy system.

  4. In the default constructor of X , call the method addTableProvider and thereby associate your class MyProvider with a data source type. The data source type is merely a String that may be chosen freely as long as it does not clash with the predefined data source types in the XMA runtime.

An example for the simplest own implementation of a XMATabularDataSourceServer would look like this:

 public class MyDataSourceServer extends TabularDataSourceServer {

    public MyDataSourceServer() {
        super();
        addTableProvider("mytype", new LOWTableProvider());
    }

First, ITableProvider requires you, of course, to provide the table data. You must implement the method provideTable , that must (among other things to be explained later) return either a TabularData or a TabularDomData object. To fill a TabularData -object, the following steps are required:

  • Define the names of the columns using the method TabularData.addColumn(String name).

  • Add rows to the table using the method TabularData.addRow (TabularDataRow r). A row itself is filled using multiple calls to TabularDataRow.add(Atom value), which requires Atom -objects to provide the table cell values.

If the table should hold a domain, you must create a TabularDomData -object where the column-structure is fixed. Therefore, instead of multiple calls to TabularData.addColumn(String name), you may use the convenience-method TabularDomData.addDomColumns(). In order to fill the domain-table with values, your added cells must comply with the structure defined in ITabularDomData .

An example for an own ITableProvider implementation which reads country information from a data source, in this case the implementation is extended from RessourceBundleProviderServer:

 public class LOWTableProvider extends RessourceBundleProviderServer {

    /**
     * The names of the reserved columns
     */
    private static final String[] DOM_COLS =
        { "COD_KEY", "SHORT_VALUE", "LONG_VALUE", "VALID_FROM", "VALID_TO" };


    public ProviderResultServer provideTable(
        XMASession session,
        TableSpec spec,
        long lastModified) {

        String domName = getDomName(spec);

        ProviderResultServer result = null;

        if (domName.equals("country")) {
            result = provideMyTable(,spec, lastModified);
        }

        if (result == null) {
            throw new SysException("No domaine \"" + domName + "\" found.");
        }

        return result;
    }

    private ProviderResultServer provideMyTable(
        TableSpec spec,
        long lastModified) {

        try {
            //This method reads the actual DS (e.g. database)
            ArrayList countries = getCountryList();

            TabularData table = new TabularDomData();

            for (int i = 0; i < DOM_COLS.length; i++) {
                table.addColumn(DOM_COLS[i]);
            }

            for (int i = 0; i < countries.size(); i++) {

                Land land = (Land) countries.get(i);

                TabularDataRow row = new TabularDataRow(table);
                row.add(new Atom(land.iso()));
                row.add(new Atom(land.kurz()));
                row.add(new Atom(land.name()));
                row.add(Atom.EMPTY_DATE);
                row.add(Atom.EMPTY_DATE);

                try {
                    table.addRow(row);
                }
                catch (IllegalArgumentException e) {

                }
            }

            ProviderResultServer result = new ProviderResultServer();
            result.table_ = table;
            return result;

        }
        catch (Exception e) {
            throw new SysException(
                e,  "Domain cannot be read.");
        }
    }

    private String getDomName(TableSpec spec) {

        String domName = spec.getProperty("name");
        if (domName == null || domName.length() == 0) {
            throw new SysException("Domain name not specified.");
        }

        return domName;
    }
}

The ITableProvider implementor is requested to provide three parameters that control how long tables may stay in client and server caches and therefore how outdated a particular table might be in terms of the client application requesting a table:

The server's in memory cache is optional. A getExpireDurationServerSecs with a value of zero indicates that it should be bypassed. In that case, every request from the XMA client or from the XMA application at the server is forwarded directly to the ITableProvider.

Every plugin in XMA must be configured in the xma-app.xml -file. The following configuration items must be given: