MicroStrategy ONE

Using Beans to Create a Java-based Task

The code sample provided below illustrates how to construct a simple Java-based task— in this example, a task that performs folder browsing. While this task is already provided out-of-the-box by MicroStrategy Web, it is used here because the purpose of this code sample is to illustrate how to build a simple Java class and folder browsing provides a good example.

The explanations below go through the code, section by section, and provide a detailed description of what each part of the code does. Because MicroStrategy Web provides a FolderBean that does much of the difficult work, the primary focus of this sample is to add some type restrictions to the query. The explanations precede each section of the code.

Adding type restrictions is the reason that this must be constructed as a Java-based task rather than as a bean-based XML task..

  • Explanation: First, you specify the name of the package to which the task class belongs and import the classes that are needed to compile this class, including classes from the com.microstrategy.web.tasks hierarchy. Classes from this hierarchy are normally needed for any Java-based task that you create.

    Copy
    Package myTasks;
    import com.microstrategy.web.beans.FolderBean;
    import com.microstrategy.web.objects.SimpleList;
    import com.microstrategy.web.tasks.TaskException;
    import com.microstrategy.web.tasks.config.TaskParameterMetadataImpl;
    import com.microstrategy.web.app.tasks.BeanTask;
    import com.microstrategy.web.app.tasks.BeanTaskRequestContext;
  • Explanation: Next, you declare your class to be a subclass of BeanTask so that it can inherit the base functionality of that class. You create only a few instance variables because keeping instance data is usually not allowed in a task due to the fact that the same class instance is used for all task invocations. In this example, you create only the class name and a place to store your type restriction parameter metadata.

    You can store the type restriction parameter metadata as an instance variable since the same metadata is used by all the instances of this task. You cannot, however, store the parameter itself in the instance since the same instance is used for all task requests. The parameter metadata is created only once, at task startup, and thus can be shared. See the Javadocs documentation as well as the rest of this example below for details on using the TaskParameterMetadataImpl class.

    Copy
    public class myFolderBrowseTask extends BeanTask {    
     /* The name of the class */    
     private final static String CLASS_NAME = "myTasks.myFolderBrowseTask";    
     /* The type restrictions parameter--created at startup, used by all instances. */    
     private TaskParameterMetadataImpl typeResParam;
  • Explanation: The registerParameterMetadata method is called for you by your base BeanTask class to register parameter information. In this example, you are interested in only one parameter, typeRestriction. After calling the super class, you check whether this is the typeRestriction parameter and, if it is, store its metadata in your instance variable.

    This method is called only on task startup and only to register the parameter metadata and not the actual parameter data itself. Every instance can make use of this metadata, while the actual, invocation-specific parameter itself is loaded from the context later in the code.

    Copy
        protected void registerParameterMetadata(
            TaskParameterMetadataImpl parameterMetadata) {
            // Register the parameter with the task metadata...
            super.registerParameterMetadata(parameterMetadata);
            // Is this the type restrictions parameter? If so, save a reference to it for later...
            if (parameterMetadata.getName().equals("typeRestriction")) {
                typeResParam = parameterMetadata;
            }
        }
  • Explanation: Two simple lines of code in the collectData(BeanTaskRequestContext) method do the entire work of getting the data for a folder browse. This method is called by your base class’s processRequest method when it attempts to collect the results of the folder browse. Before this point, your base class has already done the following:

    • Checked the parameters by calling the checkForRequiredParameters method

    • Prepared a RequestKeys object and your WebBean for use by calling the prepareRequestKeys and prepareBean methods respectively

    • Handled the event for your bean by calling the handleEvent method

    You can have overridden any or all of these other methods to modify their behavior. However, in this simple example, the methods already do exactly what you want so there is no reason to override them.

    Copy
        protected void collectData(BeanTaskRequestContext bsrContext)
            throws TaskException {
        
            // Set the type restrictions on the Folder Bean...
            setFolderTypeRestrictions(((FolderBean) bsrContext.getWebBean()),
            getTypeRestrictions(bsrContext));
            
            // Delegate to the super class to finish...
            super.collectData(bsrContext);
        }

    Once these actions have been performed successfully, you are ready to collect the data from your bean. The first line uses the BeanTaskRequestContext parameter to get your WebBean and then uses the setFolderTypeRestrictions helper method (described in the last code snippet below) to set the type restrictions parameter on it. Once that is done, you are ready to let your super class do the data collection from the bean.

  • Explanation: The getTypeRestrictions method is where you use the type restriction parameter metadata that you stored away above. Again, remember that this metadata is not the actual parameter data itself. The actual parameter data is contained in your context RequestKeys. The parameter metadata object is simply a helper that makes it easy for you to obtain the actual parameter value from the context. The parameter metadata object also applies the parameter default, if necessary, to ensure that a valid value is always returned from your getArrayValue call.

    Copy
        private String[] getTypeRestrictions(BeanTaskRequestContext bsrContext) {
            // Return an array of values separated by commas...
            return typeResParam.getArrayValue(bsrContext.getRequestKeys(), ",");
        }
  • Explanation: Finally, the setFolderTypeRestrictions helper method does the job of putting the type restrictions stored in the context onto the FolderBean. Armed with the FolderBean and the list of type restrictions, this is a simple task that consists of loading the FolderBean’s SimpleList of types, clearing it, and then looping through the passed-in restriction array to add each restriction to the FolderBean’s SimpleList.

    Copy
        /*
         * Adds the type restrictions from the filter list to the folder
         * bean's search object
         */
        private void setFolderTypeRestrictions(FolderBean fb,
            String[] typeRestriction) {
            // If you have any restrictions, apply them now...
            if (typeRestriction.length > 0) {
                // Get the list of folder type restrictions...
                SimpleList folderTypeRes = fb.getTypeRestrictions();
                // Clear it...
                folderTypeRes.clear();
                // Loop through the list of strings...
                for (int i = 0; i < typeRestriction.length; i++) {
                    try {
                        // Create an Integer object to hold the value...
                        Integer type = new Integer(typeRestriction[i]);
                        // Add it to the list of restrictions...
                        folderTypeRes.add(type);
                    } catch (NumberFormatException e) {}
                }
            }
        }
    }