Skip to Content

How to build your own custom components

Printer-friendly versionSend to friendPDF version
Intermediate

The Streamezzo SDK offers you the possibility to use components in order to help you to quickly build rich media applications and by providing customizable and prebuilt pieces of code. But components can also be seen as a development philosophy in order to capitalize your work and to stop reinventing the wheel.

You are totally free to build your own components and this tutorial will tell you the steps we follow to develop ours

This article assumes you already have working knowledge of RSP and that you have read the Components - Introduction.

Component packaging

JAR deliverable

Let's take a look at how a component is released. As previously said, a component is delivered as a library ([component name].jar) that can be used like any other third party lib.
Indeed this archive will contain the pre-compiled RSP files, i.e. the java classes equivalent to the RSP files. Having the component RSP files in your source folder is equivalent to having the component JAR in the library folder, but in this last case you do not need to re-compile the component at each build. There is another advantage: you can deliver a component while keeping the sources not accessible.

Parameters

A component is designed to be inserted into a RSP file using the <include> tag. As previously said, having the component in its JAR form is equivalent as having it in as sources; that means that you can call the <include>tag with the name of the targeted RSP as if it was in your source folder. The MANIFEST.MF of a component JAR contains a special directive that exposes the RSP files that can be included, e.g :

Rsp-Files: MyComponentContent.rsp,MyComponentView.rsp

The component can be customized by passing request attributes to the included page, therefore each component proposes Java constant classes that define all the parameters used by the component. Those constant classes are included in the component JAR. A typical component call will look like this:

<% stzRequest.addRequestAttribute(MyComponentViewConstants.PARAM,"value"); %>
Tip: For our developments we do not directly add attributes to the current request because if you want to do things properly you must remove all the attributes after the tag. This makes the include too verbose, thus we created a utility class, the RequestParameterContext object. A RequestParameterContext can hold a set of couples (name, value). The parameters are added to the request only when the setup(stzRequest) is called, and a simple call to clean(stzRequest) will remove all the added attributes. The RequestParameterContext is also designed to leave the request in the exact state as it was before, that means that if you add an attribute in your context that is already set in the request, the install call will overwrite the previous value, but the clean call will restore the previously set value.

Volume Bar Component

During this tutorial, we will create a very simple re-usable component that can be used to display the device volume level. This is how it looks like:

The component images and size are fully customizable, the caller provides the assets and the component will layout them and create an animation that will be linked to the volume level.

Project structure

Let's create the component project structure.
We consider that having a project that is always up and ready to be emulated (as is) is a good practice. That is why you must add the features one by one. So what do we need at this point to have a project ready to emulate ?
To emulate a component we need to create the component RSP files, the Java constant classes and a sample 'service' that uses the component. I am sorry but we are going to produce a significant effort just to have an empty service ;).

A component project is structured like this:

  • src/, contains the component source files
  • src/sample/, contains the sample service .rsp files
  • src_java/, contains the .java constant classes
  • lib/, contains the needed libraries
  • ant/, contains the build file

Step 1
Let's now create the first Java constant class: create a new file named VolumeBarParameters.java in src_java/com/streamezzo/volumebar. Just add the INSERT_TARGET constant.

package com.streamezzo.volumebar; /** * A simple component used to popud a volume bar. * @odp.component VolumeBar * @odp.rspFile VolumeBar.rsp * @odp.component.mainDescription */ public final class VolumeBarParameters { /** * The DEF of the Transform node where this component will be inserted. * @odp.required * @odp.type A global DEF */ public static final String INSERT_TARGET = "InsertTarget"; }
Tip: You may have noticed that there are some custom documentation tags in the javadoc, these doclets are used by the odpdoc tool to generate the component documentation.

Step 2
Let's create the main component RSPfile, VolumeBar.rsp. Notice that, as this page is designed to be included, you must NOT provide a <header> tag.
Just leave the file empty for now :

<%@page import="com.streamezzo.odp.utils.RequestUtils" %> <%@page import="com.streamezzo.volumebar.*" %> <% String insertTarget = RequestUtils.getStringRequestAttribute(stzRequest, VolumeBarParameters.INSERT_TARGET); %>

Step 3
Let's create the sample RSPfile, Sample.rsp. This RSP will load the sample images and include the component:

<%@page import="com.streamezzo.odp.utils.RequestParameterContext" %> <%@page import="com.streamezzo.volumebar.*" %>
<% RequestParameterContext params = new RequestParameterContext(); params.addParameter(VolumeBarParameters.INSERT_TARGET,"Global:VolumeBarAnchor"); params.setup(stzRequest); %> <% params.clean(stzRequest); %>

Step4
At this point the project skeleton is formed, but nothing compiles, we need to compile the .java files, create a .jar (java library) and add this JAR as a service library. A component compilation is a 2-step process :

  • First, compile the Java constant classes,
  • Second, compile the component RSP files with the previous compiled classes in the classpath.

We will use Ant to compile the Java constant classes. Let's create a build.xml file in the ant/ folder, and add a compileJava target; This target compiles the .java sources and archives them in the internal.jar file.

The internal.jar can now be added as a service library.

Release process

How to compile the component

We use the Workbench Developer's stz.server.package to create a fake server package. Then we can extract the generated Java classes.

How to package the component

The generated RSP Java files are now located in the myService.zip archive generated by the compile target. To package the component we need to create a JAR that merges the RSP generated classes plus the constant classes. As previously said, the JAR Manifest file must contain the list of all the available RSPs; this is done thanks to the pathconvert task.

How to build the component headless

As we use Workbench Developer TM Ant targets (eg :stz.server.package), the Ant build can only be launched inside a running instance of Workbench Developer TM . Nevertheless there is a way to launch Workbench Developer TM in a headless mode in order to build your component from your build machine. Notice that Workbench Developer TM must be installed on the build machine, but you'll be able to launch the build from a simple DOS command line.

How to generate the component documentation

We provide a specific tool that can generate the component generation from the Java constant classes. Our tool parses the Java classes and collects the information given by the specifics javadoc tags, the collected datas are merged into a XML file. The XML file is transformed using a xsl stylesheet. The official ODP component documentation is generated with this tool.

This a list of the odp doclets :

Class level doclet:

@odp.component
Declares that this constant class is related to the given component (e.g @odp.component VolumeBar).
@odp.rspFile
Declares that this constant class defines the attribute constants for the given RSP (e.g @odp.rspFile VolumeBar.rsp).
@odp.component.mainDescription
Declares that javadoc comment of this class is the component description. A component can have multiple Java constant classes, but only the class documentation of this class is used as the component description.
Sample:

/** * A simple component used to popup a volume bar. * @odp.component VolumeBar * @odp.rspFile VolumeBar.rsp * @odp.component.mainDescription */ public final class VolumeBarParameters

Field level doclet :

@odp.required
If this tag is present, the parameter is mandatory.
@odp.defaultValue
Declares the default value of this attribute (e.g @odp.defaultValue "SMALL")
@odp.type
The type of this attribute (e.g @odp.type Html color)
@odp.category
Can be used to group related parameters
Sample:

/** * The DEF of the Bitmap representing the full volume bar. * @odp.required * @odp.type A global Def * @odp.category Volume */ public static final String VOLUME_FULL_BITMAP = "DesignMediaControlBarVolumeFull";

Full sample

The sample source code can be downloaded here.

Share this