# Defining Capabilities and the Flow of Events

This section introduces `AdvancedExampleServlet2`. `AdvancedExampleServlet2` is
an example data source implementation that defines capabilities and the
flow of events. This section also provides step-by-step instructions on
how to run and test `AdvancedExampleServlet2`.

- [Introducing `AdvancedExampleServlet2`](https://developers.google.com/chart/interactive/docs/dev/dsl_httpservlet#intro)
- [Running and testing `AdvancedExampleServlet2`](https://developers.google.com/chart/interactive/docs/dev/dsl_httpservlet#running)

**Note** : You must complete the [Getting
Started](https://developers.google.com/chart/interactive/docs/dev/dsl_get_started) section before you begin this section.

## Introducing `AdvancedExampleServlet2`

The `AdvancedExampleServlet2` class is located in the `examples` package.
This class provides an example implementation that defines capabilities
and flow of events.

The most important parts of `AdvancedExampleServlet2` are
described in the following sections:

- [Defining the flow of events](https://developers.google.com/chart/interactive/docs/dev/dsl_httpservlet#flow)
- [Handling errors](https://developers.google.com/chart/interactive/docs/dev/dsl_httpservlet#error)
- [Using URL parameters](https://developers.google.com/chart/interactive/docs/dev/dsl_httpservlet#url_params)
- [Using capabilities](https://developers.google.com/chart/interactive/docs/dev/dsl_httpservlet#capabilities)

### Defining the flow of events

`AdvancedExampleServlet2` defines the flow of events
by overriding the `HttpServlet.doGet()` method
and calling various helper functions provided by `DataSourceHelper`.

The following snippet overrides `doGet()`. The `HttpServletRequest` parameter
encapsulates the request made by a visualization to the servlet. The `HttpServletResponse` parameter
encapsulates the response from the servlet to the querying visualization.
This snippet also sets `dsRequest` to null. `dsRequest` is used at various points throughout the rest of the code.

```
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    DataSourceRequest dsRequest = null;
```

The following snippet extracts the request parameters from `HttpServletRequest` to create the context in which the request runs.

```
    try {
      // Extract the request parameters.
      dsRequest = new DataSourceRequest(req);
```

The following snippet takes the query from the `dsRequest` object and splits
it into two separate queries. One query is called the data source
query, the other the completion query. Because the data source's
declared capability is `SELECT`, the data source query consists
of a `SELECT` operation if the `dsRequest` object
includes a `SELECT` operation.
The completion query
consists of all other operations required by the request, which might also
include a `SELECT` operation. For example, if the query requested
is `SELECT a ORDER
BY b`,
then the data source query will be `SELECT a, b` and the completion
query will be the same as the original query `SELECT a ORDER BY b`.

```
      // Split the query.
      QueryPair query = DataSourceHelper.splitQuery(dsRequest.getQuery(), Capabilities.SELECT);
```

The following snippet takes the data
source query created by the previous snippet and the `HttpServletRequest,` and
creates a data table. See the [Using
capabilities](https://developers.google.com/chart/interactive/docs/dev/dsl_httpservlet#capabilities) section
for more details.

```
      // Generate the data table.
      DataTable data = generateMyDataTable(query.getDataSourceQuery(), req);
```

The following code takes the completion
query produced when the query was split, the datatable produced
by the previous snippet, and the user locale from the
querying visualization. The code then creates a new
data table.

```
      // Apply the completion query to the data table.
      DataTable newData = DataSourceHelper.applyQuery(query.getCompletionQuery(), data,
          dsRequest.getUserLocale());
```

The following code takes the data
table produced by the previous snippet, and the request parameters from `HttpServletRequest`. The code
then sets the servlet response. The servlet container returns this response
to the querying visualization.

```
      DataSourceHelper.setServletResponse(newData, dsRequest, resp);
```

### Handling errors

The following snippet catches an exception,
gets the appropriate message, formats the response, and sets the servlet
response. If `dsRequest` is
null, the
`DataSourceRequest` is not available, possibly due to failure
of the constructor. In this case, the `HttpRequest` is
used instead of the `DataSourceRequest`.

```
    catch (RuntimeException rte) {
      log.error("A runtime exception has occured", rte);
      ResponseStatus status = new ResponseStatus(StatusType.ERROR, ReasonType.INTERNAL_ERROR,
          rte.getMessage());
      if (dsRequest == null) {
        dsRequest = DataSourceRequest.getDefaultDataSourceRequest(req);
      }
      DataSourceHelper.setServletErrorResponse(status, dsRequest, resp);
    } catch (DataSourceException e) {
      if (dsRequest != null) {
        DataSourceHelper.setServletErrorResponse(e, dsRequest, resp);
      } else {
        DataSourceHelper.setServletErrorResponse(e, req, resp);
      }
    }
```

### Using URL parameters

The following snippet takes the data
source query that was created when the query was split and the `HttpServletRequest`.
The `HttpServletRequest` can optionally include a `tableId` parameter
specified as a URL. This `tableId` parameter
determines which data table is returned as follows:

- If the `tableId` parameter is omitted, or is anything other than `planets`, the data source returns the animals data table.
- If the `tableId` parameter is specified as `planets`, the data source returns the planets data table.

When you write your own code to return a data table, you decide
which parameters to take.

```
  private DataTable generateMyDataTable(Query query, HttpServletRequest req)
      throws TypeMismatchException {
    String tableID = req.getParameter("tableId");
    if ((tableID != null) && (tableID.equalsIgnoreCase("planets"))) {
      return generatePlanetsTable(query);
    }
    return generateAnimalsTable(query);
  }
```

### Using capabilities

The following snippet takes the query and generates the `animals`
data table.

```
private DataTable generateAnimalsTable(Query query) throws TypeMismatchException {
  DataTable data = new DataTable();
  List requiredColumns = getRequiredColumns(query,
      ANIMAL_TABLE_COLUMNS);
  data.addColumns(requiredColumns);

  // Populate the data table
  for (String key : animalLinksByName.keySet()) {
    TableRow row = new TableRow();
    for (ColumnDescription selectionColumn : requiredColumns) {
      String columnName = selectionColumn.getId();
      if (columnName.equals(ANIMAL_COLUMN)) {
        row.addCell(key);
      } else if (columnName.equals(ARTICLE_COLUMN)) {
        row.addCell(animalLinksByName.get(key));
      }
    }
    data.addRow(row);
  }
  return data;
}
```

The following snippet takes the query and generates the `planets`
data table.

```
private DataTable generatePlanetsTable(Query query) throws TypeMismatchException {
  DataTable data = new DataTable();
  List requiredColumns = getRequiredColumns(
      query, planetTableColumns);
  data.addColumns(requiredColumns);

  // Populate data table
  for (Planet planet : Planet.values()) {
    TableRow row = new TableRow();
    for (ColumnDescription selectionColumn : requiredColumns) {
      String columnName = selectionColumn.getId();
      if (columnName.equals(PLANET_COLUMN)) {
        row.addCell(planet.name());
      } else if (columnName.equals(MASS_COLUMN)) {
        row.addCell(planet.getMass());
      } else if (columnName.equals(GRAVITY_COLUMN)) {
        row.addCell(planet.getSurfaceGravity());
      } else if (columnName.equals(MOONS_COLUMN)) {
        row.addCell(planet.getNumberOfMoons());
      }
    }
    data.addRow(row);
  }
  return data;
}
```

## Running and Testing `AdvancedExampleServlet2`

This section provides instructions on how to run and test `AdvancedExampleServlet2`.

To run and test `AdvancedExampleServlet2`, update
your web application, and set up a visualization that queries the data
source, as described in the following sections:

- [Updating a Web Application on Apache Tomcat](https://developers.google.com/chart/interactive/docs/dev/dsl_httpservlet#webapp)
- [Using a Visualization to View the Data](https://developers.google.com/chart/interactive/docs/dev/dsl_httpservlet#visualization)

### Updating a Web Application on Apache
Tomcat

Follow or adapt the instructions below to update your web application
on Apache Tomcat. These instructions are specific to Apache Tomcat on a
Windows system:

1. The `web.xml` file you previously copied to the `WEB-INF` directory already contains the definition and mapping required for this example. The lines that define this are:  

   ```
   <servlet>
     <servlet-name>AdvancedExampleServlet2</servlet-name>
     <description>
     AdvancedExampleServlet2
     </description>
     <servlet-class>AdvancedExampleServlet2</servlet-class>
   </servlet>
     
   <servlet-mapping>
     <servlet-name>AdvancedExampleServlet2</servlet-name>
     <url-pattern>/advanced</url-pattern>
   </servlet-mapping> 
   ```
2. Start Tomcat, or restart Tomcat if it is already running.  
3. Click the following link:<http://localhost:8080/myWebApp/advanced>  
   The screen displays 6-7 lines of text, depending on your screen width. The text begins with `google.visualization.Query.setResponse ` and ends with `{v:'http://en.wikipedia.org/wiki/Tiger'}]}]}});`  
   This is the response that the example CSV data source sends to a visualization.

### Using a Visualization
to View the Data

The `all_examples.html` file in the `<data_source_library_install>/examples/src/html` directory
can be used to view a visualization of the data.

The following snippet from `all_examples` specifies
the `advanced` servlet, the `planets` table, a select query, and
a bar chart visualization.

```
query = new google.visualization.Query('advanced?tableId=planets&tq=select planet,mass');
...
var chart = new google.visualization.BarChart(document.getElementById('advanced_div'));
```

For an explanation of the other visualizations included in `all_examples.html`,
see the [Using an External Data Store](https://developers.google.com/chart/interactive/docs/dev/dsl_csv) section.

For more information on how to specify a visualization and use the query
language, see [Using Charts](https://developers.google.com/chart/interactive/docs) and
the [Query Language Reference](https://developers.google.com/chart/interactive/docs/querylanguage).

Follow, or adapt, the instructions below to view a visualization of
the data provided by the advanced data source:

1. If you haven't already done so, copy the `all_examples.html` file from the `<data_source_library_install>/examples/src/html` directory   
   to the `<tomcat_home>/webapps/myWebApp/` directory.  
2. Click the following link: <http://localhost:8080/myWebApp/all_examples.html> in a browser. You should see the following:  

   ![](https://developers.google.com/static/chart/interactive/docs/dev/advanced.png)

## Next Steps

To further explore the examples provided with the library, see [Examples
Quick Reference](https://developers.google.com/chart/interactive/docs/dev/dsl_about#quick). To learn more about implementing a complex
data source, see [Implementation Tips](https://developers.google.com/chart/interactive/docs/dev/dsl_key_concepts).