This section covers some tips that will help you write more complex implementations of the library:
- Using Your Own Servlet
- Defining Capabilities
- Customizing the Flow of Events
- Passing Parameters to
DataTableGenerator.generateDataTable
- Implementing a Non-servlet Data Source
Using Your Own Servlet
The simplest data source implementations inherit from the library's DataSourceServlet
class.
To inherit from a class other than DataSourceServlet
, implement
a data source as follows:
- Implement the
DataTableGenerator
interface and overridegetCapabilities()
andgenerateDataTable()
. - Call
DataSourceHelper.executeDataSourceServletFlow()
from within your servlet's code to run the data source flow. This method takes the following parameters :- An
HttpServletRequest
object. - An
HttpServletResponse
object. - Your implementation of the
DataTableGenerator
interface from step 1 above. - A boolean to specify restricted or unrestricted access mode.
- An
For example, if you want to inherit your servlet from another servlet
class, called AuthServlet
that provides built-in authentication,
you can rewrite the SimpleServletExample
to inherit AuthServlet
rather
than DataSourceServlet
as follows:
- Implement the
DataTableGenerator
interface. - Move
generateDataTable()
from yourDataSourceServlet
implementation to yourDataTableGenerator
implementation. - Override
getCapabilities()
in yourDataTableGenerator
implementation to returnCapabilities.None
. - Call
DataSourceHelper.executeDataSourceServletFlow()
from within your servlet code (doGet()
ordoPost()
), and pass yourDataTableGenerator
implementation. This method runs the entire flow of the datasource, including rendering the data source results into the servlet response.
You can use the same technique if you are using a servlet framework
in which you normally inherit an abstract class provided by the framework.
For example, if you are using WebWork you might want to inherit the ActionSupport
class.
Defining Capabilities
If your data store contains a large amount of data, and you want
to increase the efficiency of your data source, you can use the querying
capabilities of your data store. For example, suppose that your data store
is a database, and the database has a large number of columns. If a visualization
requests only a few of those columns, then running a SELECT
operation
within the database is more efficient than retrieving all the columns and
using the library's querying capabilities to perform the SELECT
.
To implement SELECT
capabilities, you write code
to run a SELECT
operation within the database and to return
a data table.
Use the Capabilities
enum
to define the querying capabilities that your code
provides. Available options are:
NONE
: the default, your code provides no query operations.SQL
: your code provides SQL query operations.SORT_AND_PAGINATION
: your code provides both sort and pagination query operations.SELECT
: your code provides a select operation.ALL
: your code providesSQL
,SORT_AND_PAGINATION
, andSELECT
operations.
Note: In all cases the library handles any query operations that are not provided by your code.
To implement a capability other than NONE
, override Capabilities.getCapabilities()
and
implement DataTable.generateDataTable()
to query the data
store and return a data table.
Three of the examples illustrate how to implement capabilities: AdvancedExampleServlet
,
AdvancedExampleServlet2
, and SqlDataSourceServlet
.
All are in the example
package. AdvancedExampleServlet2
is
discussed in Defining Capabilities and the Flow of Events.
Customizing the Flow of Events
The default flow of events is defined in DataSourceHelper.executeDataSourceServletFlow
.
The default flow is as follows:
- Extract and parse query parameters.
- For restricted access mode only, verify that the request originates from the same domain as the servlet.
- Parse the request to create two query objects: the data source query
and the completion query. Pass the data source query to your implementation
of
generateDataTable()
. - Your implementation of
generateDataTable()
generates a data table. - Run the completion query on the data table generated in step 5.
- Render the data table into the format specified by the visualization and set the servlet response.
To specify your own flow of events, call the
helper functions in datasource.DataSourceHelper
. See
Defining Capabilities and the Flow of Events for an example
implementation.
Passing Parameters to DataTableGenerator.generateDataTable
You can use the HttpServletRequest.setAttribute
to pass
data that is not part of a query or HttpServletRequest
object
to DataTableGenerator.generateDataTable
. Example code is provided
below.
In your servlet's code, put the object you want to pass into the HttpServletRequest
as
follows:
request.setAttribute("my_object_name", myObject); DataSourceHelper.executeDataSourceServletFlow(request, response, dataTableGenerator);
In your dataTableGenerator
interface implementation, get the object from the HttpServletRequest
as follows:
public DataTable generateDataTable(Query query, HttpServletRequest request){ Object myObject = request.getAttribute("my_object_name"); // Add your code to manipulate myObject here }
Implementing a Non-servlet Data Source
If you implement the library without using a servlet, you can
use only those classes and helper functions that do not require
a servlet environment. These include the Query
and DataTable
classes and some of the DataSourceHelper
functions
such as parseQuery
, applyQuery
, validateQuery
and splitQuery
.
You can use these classes and functions to do the following:
- Parse a visualization query.
- Split the query into a data source query and a completion query.
- Run the completion query to generate a data table.
- Return the data table to the visualization in
HTML
,CSV
, orJSON
format.