MicroStrategy ONE

Custom Bean

In MicroStrategy Web, a bean is the object used to collect the data that is displayed to end users. You can create custom beans and use them just like the out-of-the-box beans that are part of the MicroStrategy Web application. Custom beans can be useful in a number of ways, including:

  • Providing custom editor functionality which is responsible for editing the content of metadata beans

These beans are generally responsible for handling editor-related events and persisting state information about the editor that would not be appropriate to persist in the metadata bean. For example, in a tabbed editor, the bean must remember which tab is currently being displayed and handle the event to modify the tab. These events are purely GUI-related and belong in a GUI-related bean.  

  • Providing custom data display functionality

These beans are generally responsible for data display that is not available from out-of-the-box beans. For example, if it is necessary to display information about the current database load, a custom bean can be used to gather the database statistics and display the content to the end user. Using a custom bean allows you to encapsulate data collection and display in an easily upgradable component.

To create a custom bean, you must write one or more Java classes.

You can create a custom bean programmatically, rather than by defining it in the Page Configuration file, but this is not the recommended practice. Defining the bean in the Page Configuration file allows you to centralize changes in one place, rather than having to make changes throughout the code. This reduces the amount of work that needs to be done and makes it easier to upgrade.

Every bean class must implement the com.microstrategy.web.beans.WebComponent interface. This allows the bean, whether system or custom, to be a part of the WebComponent hierarchy, which includes the Web application itself, all the pages, and all the beans. In general, a custom bean class does not need to explicitly implement all the methods of this interface. Instead, the class can extend an existing abstract class implementation, such as com.microstrategy.web.app.beans.AbstractAppComponent, as shown in the code sample below.

public class CustomBean extends AbstractAppComponent

This minimizes the amount of work required to implement the new bean.

You do need to implement all the methods of the WebComponent interface, but you can inherit most of them, eliminating the need to explicitly implement them.

The code in a custom bean class is responsible for the following:

Adding persistence to the bean

Your bean class must implement an interface that supports persistence. Persistence is a mechanism by which a bean can be configured to remember its state between requests so that the state can be retrieved in subsequent operations. If you want a custom bean to be able to persist its state information automatically across requests, you must specify that the bean class implements the com.microstrategy.web.beans.RequestPersistable interface, as shown in the code sample below.

public class CustomBean extends AbstractAppComponent

implements RequestPersistable {...}

The easiest way to add persistence to a custom bean is to have the bean class extend the com.microstrategy.web.app.beans.AbstractPersistableAppComponent interface, as illustrated below, and implement its doFlatState method.

public class CustomBean extends AbstractPersistableAppComponent

...

protected void doFlatState(FlatStateSerializer input, int howMuchState, FlatStateTokenizer tokenizer) {

    boolean saving = (input != null);

    if (saving) {

        input.addStr(getFirstText());

        input.addStr(getSecondText());

    } else {

        setFirstText(tokenizer.nextStr());

        setSecondText(tokenizer.nextStr());

    }

}

The doFlatState method is responsible for saving and restoring the state. If a FlatStateSerializer is found, it is assumed that the state needs to be saved. The state information is simply appended in order when the state is saved and then read off in that same order when the state is restored. If a FlatStateSerializer is not found, the state is restored using the FlatStateTokenizer. In certain situations, it may be necessary to override the implementation of the saveState or restoreState methods defined by the Persistable interface.

The doFlatState method defines a howMuchState parameter, which can be used to modify the amount of state information that is persisted. The howMuchState parameter can have one of the values listed below.

Value Description

0

Persist minimum state information

(howMuchState=0)

1

Persist typical state information (generally represents information about the component's initialization and all changes that have been made to it)

(howMuchState=1)

2

Persist maximum state information (usually represents the complete definition of the component and all changes that have been made to it)

(howMuchState=2)

For additional details on persistence, refer to documentation on the Persistable interface.

In the Page Configuration file, you define the custom bean as persistable by setting the persist-mode attribute to a value other than 1 (as described in the New Bean based on an Existing System Bean topic). This  instructs the application to persist the bean by calling methods on these interfaces. Since it is the responsibility of the bean to decide the information that needs to be persisted, the bean should extend AbstractPersistableAppComponent and implement the doFlatState method, as described above. The code sample,SerializeSampleBean.java, for saving and restoring the state of a bean is located insamples/java/beansinside the MicroStrategy SDK installation folder.

Making the bean transformable

The recommended practice in MicroStrategy Web is for the bean class to retrieve the data (from Intelligence Server or some other data source) and for a transform class to handle the presentation of that data to the user. Transforms specialize in taking data conforming to a given bean’s structure and transforming it into final content via a MarkupOutput object. The final content is typically HTML, but it can also include other formats, such as Wireless Markup Language (WML), plain text, or binary data. A single bean can be rendered by multiple transforms, including ones that produce different final HTML output as well as those that produce non-HTML output. In order for MicroStrategy Web to be able to assign a transform to the bean automatically, the bean class must implement the Transformable interface, as shown in the code sample below.

public class CustomBean extends AbstractAppComponent

implements RequestPersistable, Transformable { … }

By default, the methods in the Transformable interface are already implemented by AbstractAppComponent.

Creating a new bean instance

The easiest way to instantiate a custom bean is to use a public no-arg constructor on the bean class.

public CustomBean(){

}

Setting properties on the bean

Typically, public properties of a bean are exposed through get() and set() methods in the bean class. The application automatically maps any public methods of the form setPropertyName to be properties (initialization and request properties) that can be set using the Page Configuration file.

Initialization properties are used when a bean is initialized and typically represent default values. They are set immediately after the bean is instantiated, but before the state of the bean is restored. The source for initialization properties is generally a constant or a preference. Initialization properties should not depend on a specific request, but instead serve to provide details about how the bean should operate once the remainder of its properties are set. Examples of common initialization properties include: 

  • Maximum wait time for a report to execute

    This value is often the same regardless of the report to be executed. 

  • Number of rows in a report to fetch at one time (such as incremental fetch settings)

    This value can be drawn from user preferences and is the same regardless of what report is executed. 

  • How often Web Universal polls Intelligence Server

    This value is generally independent of the report or document executed.

Request properties are typically dynamic values that are the result of requests by the user at runtime. They are set after the bean state has been restored. The source for request properties is generally a user request, such as a link clicked by the user. Request properties should relay information specific to a user's unique request to a page. Examples of common request properties include: 

  • Report ID, Template ID, and Filter ID for a report execution request 

  • Message ID of an existing report instance in the event a manipulation is performed 

  • Folder ID of a folder whose contents are to be displayed

    A folder ID can be both an initialization and a request property. For example, when a FolderBean initializes itself, it needs the default folderID of the folder whose contents are to be displayed. This default folderID is defined as an initialization property. This is different from the situation where a user is navigating within subfolders. In this case, the folderID for the subfolder must be passed to the FolderBean so that it knows which subfolder's contents to display. The bean has no information about this folderID  when it initializes itself, but instead receives it as a request property when the user makes the selection.

  • View mode of the report request

A custom bean can have both initialization and request properties. For each property that you include in the definition of a custom bean in the Page Configuration file, you must provide corresponding get() and set() methods on the custom bean class. These methods can then be implemented as <property> nodes (beneath either <init-properties> or <request-properties>) in the definition of a <web-bean> in the Page Configuration file.

For example, the following <property> node in the definition of a custom bean in the Page Configuration file:

<property name="viewMode" source="request" type="int" value="reportViewMode"/>

would have corresponding get() and set() methods in the bean class for that custom bean:

public int getViewMode();

public void setViewMode(int viewMode);

Creating the event handler for the bean

To create the event handler for a bean, override the newDefaultEventHandler method in the bean class and create the event handler there.

protected WebEventhandler newDefaultEventHandler(){

   return new CustomBeanEventHandler();

}

The first time the getWebEventHandler method is called, the newDefaultEventHandler method will be called to initialize the custom event handler. (The infrastructure to support this is in AbstractWebComponent.getWebEventhandler.)

Retrieving bean data

A custom bean must implement the core method, collectData.

public result collectData();

After properties have been set on the bean instance, the collectData method retrieves data for the bean instance from a data source, such as Intelligence Server. The presentation of this data to the user is almost always handled separately in a transform associated with the bean through a style.