Skip to Content

How to write a custom ResultSetFilter in SMP

Result Set Filter

General InformationHeader 2
Used PlatformSUP 2.2 SP02, SMP 2.3
TechnologyMBO-based
Date2013-04-26

Introduction

This document provides a guide on how to write a custom ResultSetFilter.

A result set filter is a custom java class an experienced developer writes in order to specifically manipulate the rows or columns of data returned from a read operation for an MBO. When a read operation returns data that does not completely suit the business requirements for your MBO, you can write and add a filter to the MBO to customize the data into the form you need. A filter can be written to add, delete, or change columns as well as to add and delete rows.

You can chain multiple filters together. Multiple filters are processed in the order they are added, each applying an incremental change to the data. Consequently, Sybase recommends that you always preview the results. After you preview the MBO, notice that the MBO has a different set of attributes than it would have had directly from the read operation. You can map and use the altered attributes in the same way you would a regular attribute from an unfiltered read operation.

Note: The filter interfaces are defined in terms of java.sql.ResultSet and java.sql.ResultSetMetaData, but these standard JDBC interfaces tend to be read-only implementations. To change data, use a CachedRowSetImpl.

Preparation

You should at first prepare your MobileSDK as described in Debugging Filter Classes. After that you can Setup of a ResultSet Filter and implement the filter, e.g. as described in the example in Example of a custom ResultSet Filter .

Debugging Filter Classes

You can set debugging options to view the output stream when using System.out.printIn in filter classes to help you debug

your filter classes.

  1. Go to <SAP Mobile SDK>\Eclipse and edit the MobileWorkSpace.bat file.
  2. Search for: start "SAP Mobile WorkSpace" "%ECLIPSE_ROOT%\eclipse.exe"
    If the -vm options is specified, replace javaw.exe with java.exe.
    Note: The javaw.exe command is the same as the java.exe command except that with javaw.exe, there is no associated console window.
  3. Add at the end of this line:  -debug
  4. Start your MobileSDK (MobileWorkSpace.bat)
    A Java console window appears, inside all Java output will be printed.

After that you can use in your Java classes System.out.println(“output”) to write into the Java output window.

Setup of a ResultSet Filter

When you create a MBO in the MobileSDK you have to define a data source. After choosing the data source you can specify the “Definition”. In this step expand “Result Set Filters” and click “Create” to create a new Java class which will be your filter. You can also add a filter to an already created MBO by choosing the MBO, then switching in the properties to Attributes > Definition > Edit…

Note: You will only get the values inside your record set which you defined in the “XSLT” schema. In this picture, you can see and edit the schema by marking “XSLT1” and pressing on “Edit…”!

Always use the “Preview” functionality to test if you are receiving correct data.

Example of a custom ResultSetFilter

package com.test;

import java.sql.ResultSet;

import java.sql.ResultSetMetaData;

import java.util.Iterator;

import java.util.Map;

import java.util.Set;

import com.sybase.uep.eis.ResultSetFilter;

import com.sybase.uep.eis.ResultSetFilterMetaData;

import java.util.HashMap;

public class Testfilter implements ResultSetFilter, ResultSetFilterMetaData {

          String separator = System.getProperty("line.separator");

          @Override

          public ResultSetMetaData getMetaData(ResultSetMetaData arg0, Map<String, Object> arg1) throws Exception {

                    return arg0;

                              }

          @Override

          public ResultSet filter(ResultSet arg0, Map<String, Object> arg1) throws Exception {

                    System.out.println(separator + "Starting filtering..." + separator);

                    ResultSetMetaData rsmd = arg0.getMetaData();

                    int columnsNumber = rsmd.getColumnCount();

                    System.out.println(separator + "ResultSet MetaData" + separator);

                    System.out.println("Number of Columns: " + columnsNumber + separator);

                        System.out.println("MetaData of ResultSet" + separator);

                        for (int i = 1; i <= columnsNumber; i++) {

                          System.out.println("Column Number: #" + i);

                          System.out.println("Column Name: " + rsmd.getColumnName(i));

                          System.out.println("Column Type: " + rsmd.getColumnTypeName(i));

                          System.out.println();

                        }

                    System.out.println(separator + "ResultSet Data" + separator);

                    while (arg0.next()) {

                              //print out the column with name “productId”

                              System.out.println("Product Id: " + arg0.getString("productId"));

                              System.out.println("text3: " + arg0.getString("text3"));

                              System.out.println("OnlineShop stock: " + arg0.getInt("onlineshopStock"));

                              System.out.println();

                    }

                    System.out.println("Number of rows in ResultSet: " + counter);

                    System.out.println(separator + "HashMap Data" + separator);

                    for (String key: arg1.keySet())

                    {

                              System.out.println("Key: " + key);

                              System.out.println("Value: " + arg1.get(key));

                    }

                    System.out.println();

                    return arg0;

                              }

          @Override

          public Map<String, Class> getArguments() {

                    return new HashMap<String, Class>();

          }

}

After running this filter, e.g. with executing the “Preview” in Mobile SDK, the metadata structure, the result set and the Hashmap content is printet in the Java console.

For example like this:

Then you would know that your record set is importing 7 columns, you know the name and the type, so you can get the corresponding data with the getter methods of the ResultSet,

e.g.rs.getString(“productId”) or rs.getInt(“onlineshopStock”)

MetaData of a ResultSet

You can use the MetaData of a ResultSet to find out which columns are stored inside the ResultSet.

//arg0 of type ResultSetMetaData (get it from the ResultSet with rs.getMetaData())

int numberOfColumns = arg0.getColumnCount();

System.out.println("resultSet MetaData column Count=" + numberOfColumns);

for (int i = 1; i <= numberOfColumns; i++) {

  System.out.println("column MetaData ");

  System.out.println("column number " + i);

  // indicates the designated column's normal maximum width in

  // characters

  System.out.println(arg0.getColumnDisplaySize(i));

  // gets the designated column's suggested title

  // for use in printouts and displays.

  System.out.println(arg0.getColumnLabel(i));

  // get the designated column's name.

  System.out.println(arg0.getColumnName(i));

  // get the designated column's SQL type.

  System.out.println(arg0.getColumnType(i));

  // get the designated column's SQL type name.

  System.out.println(arg0.getColumnTypeName(i));

  // get the designated column's class name.

  System.out.println(arg0.getColumnClassName(i));

  // get the designated column's table name.

  System.out.println(arg0.getTableName(i));

  // get the designated column's number of decimal digits.

  System.out.println(arg0.getPrecision(i));

  // gets the designated column's number of digits to right of the decimal point.

  System.out.println(arg0.getScale(i));

  // indicates whether the designated column is automatically numbered, thus read-only.

  System.out.println(arg0.isAutoIncrement(i));

  // indicates whether the designated column is a cash value.

  System.out.println(arg0.isCurrency(i));

  // indicates whether a write on the designated column will succeed.

  System.out.println(arg0.isWritable(i));

  // indicates whether a write on the designated column will definitely succeed.

  System.out.println(arg0.isDefinitelyWritable(i));

  // indicates the nullability of values in the designated column.

  System.out.println(arg0.isNullable(i));

  // Indicates whether the designated column is definitely not writable.

  System.out.println(arg0.isReadOnly(i));

  // Indicates whether a column's case matters in the designated column.

  System.out.println(arg0.isCaseSensitive(i));

  // Indicates whether a column's case matters in the designated column.

  System.out.println(arg0.isSearchable(i));

  // indicates whether values in the designated column are signed numbers.

  System.out.println(arg0.isSigned(i));

  // Gets the designated column's table's catalog name.

  System.out.println(arg0.getCatalogName(i));

  // Gets the designated column's table's schema name.

  System.out.println(arg0.getSchemaName(i));

Logging into SUP serverlog

Finally, starting with SUP 2.2 the existing "logging buckets" you can see from SCC have been extended (loggerBucketMappings.properties) to include sup.custom.[bucket-type].* loggers. So if your ResultSetFilter class is declared to be in

package sup.custom.dataservices.xxxxx;

import java.util.logging.Logger;

public class MyCustomRSFilter implements ResultSetFilter, ResultSetFilterMetaData

{

    private static final LOG = Logger.getLogger(MyCustomRSFilter.class.getName());

    ...

    LOG.warning("whatever");

Then if you set the DataServices logging level to warning or lower, your custom filter's log messages will go into the SUP server log file tagged as from the DataServices component.

Source and Additional Information

ResultSetFilter Sample

http://mobility-internal.sybase.com/questions/5603/do-you-have-a-sample-for-a-resultsetfilter-that-changes-the-data-from-eis

Another Example of a Resultset Filter

http://mobility-internal.sybase.com/questions/17109/any-example-for-result-set-filter-collaborating-with-bapi-data-source

Data Filtering API Guide (outdated, but gives a nice overview)

http://www.sybase.com/files/Technical_Documents/SUP12_DataFilteringAPI_Cookbook.pdf

Tags: