UIX Developer's Guide |
Contents |
Previous |
Next |
This chapter discusses how UIX can be used to display various types of media in your web applications. Particular emphasis is given on how to use the Oracle interMedia and BC4J bindings to store your media content in a database. The chapter contains the following sections:
At this point, you are probably already familiar with how to display static media in
your UIX pages. Static media consists mostly of images which are inlined into your
content, and they are easily displayed using the UIX <image>
component. However,
if your application calls for dynamic data such as audio or video to be displayed to the
user, you will need to use the <media>
component.
The purpose of the <media>
component is to simplify the configuration of the
wide array of media types available to developers. For instance, the Quicktime, Real,
and Windows formats for video all have different mechanisms for rendering in a browser,
as well as differences in sizing and control. the <media>
component performs two
useful functions for the developer: it helps choose which media player is most appropriate
for a particular user, and it helps abstract the differences in configuration APIs for the
developer.
The <media>
component will render the appropriate output to suggest to the
user's device which media player to use.
In some cases, there really is no choice on which media player should be used because
the type of content the developer has chosen may only be supported by one player. For
instance, video files encoded in a Quicktime format may require that the user have a
Quicktime player on his or her device. The following example shows how to specify that a movie
called "trailed.mov" should be played with the Quicktime player:
<media source="trailer.mov" player="quicktime"/>
However, audio encoded in the .mp3
format may be able to be played by multiple players. If the developer does not specify
a specific player, UIX will attempt to choose the best one. If UIX encounters the following
example:
<media source="newSong.mp3"/>
it will use a set of rules to determine which media player to use for each user.
contentType
attribute is specified on the media tag, UIX will
use this, in conjunction with information automatically sent as part of the user's
request, to figure out a media player to use. If UIX can determine this information
from the user's request, it will override even the player
attribute.
Note that it is always possible for developers to simply use the <link>
element as the mechanism for displaying media. this means that the media will not
render inline, but will instead rely on the user to follow the link to see the media. This
can be particularly useful for user devices with slower connections or less memory, where
loading the media automatically may prove problematic.
Choosing the media player is only the first step, however, and a developer also has the ability to choose more advanced display options. UIX abstracts these choices into APIs that work across the various players. Note that many of these options are hints, and some may not work for a given player.
For sizing, the "width" and "height" attributes can be used to request a specific size that the content should take when shown to the user. However, various players display extra content around the media clip such as control buttons and borders, so if you choose to use those two attributes you might not be allocating enough space for a particular player. Since each player has different controls, it can be difficult to predict the size you need.For this reason, UIX provides the "innerWidth" and "innerHeight" attributes. If a developer sets these two attributes to be the size of the actual media content, UIX will attempt to add the right amount of additional padding to this size to accommodate the controls of the player being used. This is generally the better choice. An example follows:
<media src="trailer.mov" innerWidth="320" innerHeight="240"/>
In this case, the movie trailer to be shown is 320 pixels wide and 240 pixels high, and UIX will add additional space in the user's device to accommodate the player's controls.
UIX also provides attributes for more advanced settings such as: whether or not to start play without a user action; how many times to repeat the content; what types of controls to display on the player; and what messages to display to the user while content download is taking place. For more information on these advanced settings, consult the programming reference.
Now that you've seen how to display media in a UIX application, you may be interested in ways to store and update that media content. For this, Oracle provides a technology called interMedia.
Oracle interMedia enables the Oracle database to manage multimedia content such as image, audio, video, and other digital media in an integrated fashion with enterprise information. This means that complex multimedia data can be stored, retrieved, and manipulated by an Oracle database in the same fashion as traditional relational data.
You will need a basic understanding of database storage concepts to utilize the remaining conten in this chapter. In addition, you will need knowledge of the Business Components for Java (BC4J) framework and the UIX bindings to it to proceed.
Based on the object-relational extensions of Oracle database, interMedia
uses database object types -- similar to Java or C++ classes -- to describe
multimedia data. As of Oracle8i, the interMedia object types are created
as a package at installation under the database user ORDSYS
and consist
of ORDAudio
, ORDImage
, and ORDVideo
, describing
digitized audio, image, and video, respectively. Oracle9i introduces one more object type:
ORDDoc
, for describing generic media content. An instance of these
object types consists of attributes -- including metadata and the media
data -- and methods. Media data is the actual audio, image, or video
while the metadata is information about the media, such as its length,
compression type, or format. The methods are procedures that can be
performed on the media such as "setProperties", "process", "getDataInFile", etc.
For Java developers using JDBC, interMedia provides an "interMedia Java Classes" library to support retrieval of media content from interMedia database objects and upload of media content into interMedia database objects. It also supports invocation of interMedia database object methods to perform various media-related operations. For more information on using JDBC to access interMedia, consult the interMedia documentation distributed with your database.
For BC4J developers, interMedia provides an "interMedia BC4J Domain Classes" library, which is based on the "interMedia Java Classes". The BC4J framework helps developers by providing automatic mapping between the database object types and the domain classes. BC4J developers can use the interMedia BC4J domain classes to retrieve content from or upload content to an Oracle database. These domain classes also support the invocation of interMedia database object methods to perform various media related operations.
The UIX BC4J bindings also provide the foundation for the UIX interMedia
integration. When using the interMedia BC4J domain classes, the BC4J framework treats
interMedia database object types in the same fashion as any other
database types, such as VARCHAR2. The BC4J framework creates interMedia
domain objects for interMedia database objects just as it creates String
objects for those VARCHAR2
values. The interMedia BC4J domain classes work
seamlessly in the BC4J framework with Row
, ViewObject
,
ApplicationModule
, and other BC4J objects.
Several existing UIX user interface components, including <image>
, <media>
, and <link>
, can
be used to represent multimedia content. The interMedia UIX integration uses
these beans to display media content stored in interMedia. In addition, a few new uiXML elements
have been created to bind interMedia database types to these
components. The new interMedia uiXML elements are <bc4j:image>
,
<bc4j:media>
, and <bc4j:link>
.
For media content upload, two new uiXML elements,
<bc4j:fileUpload>
and <bc4j:messageFileUpload>
are provided to generate file upload form
fields.
Some existing uiXML elements are retrofitted to add support for
interMedia. They are <bc4j:input>
and <bc4j:messageInput>
.
Users don't have to learn a new way of developing uiXML applications. Using interMedia in UIX just means using the new uiXML elements in the familiar BC4J uiXML application.
Let's assume the EMP
table (discussed in Business Components for Java Integration) has an additional column called "EmpPic" of type ORDSYS.ORDIMAGE
. This "EmpPic" column is
used to store employee pictures. We will use this new EMP
table in the
next examples.
The following SQL code shows how to create a database table with an interMedia
ORDSYS.ORDIMAGE
column:
create table MediaEmp (EMPNO number(4) primary key,
ENAME varchar2(10),
HIREDATE date,
SAL number(7,2),
EMPPIC ordsys.ordimage);
The uiXML BC4J bindings currently allow developers to choose whether to explicitly specify data types of user interface components, known as "manual" mode, or allow the framework to automatically determine the types of components, known as "automatic" mode.
In automatic mode, the <bc4j:keyStamp>
and <bc4j:columnStamp>
elements
automatically pick up the interMedia column. The <bc4j:input>
element
automatically assigns an <image>
to the interMedia attribute for
rendering. So the sample code in the Business Components for Java Integration chapter doesn't even need to
change to have the employee picture displayed in the browser.
<bc4j:rootAppModuleScope name="EmpAppModule">
<contents>
<bc4j:viewObjectScope name="CurrentDeptEmpsVO">
<contents>
<bc4j:table name="emps" automatic="true">
<bc4j:keyStamp>
<bc4j:rowKey name="key" />
</bc4j:keyStamp>
<bc4j:columnStamp>
<bc4j:column>
<columnHeader>
<bc4j:sortableHeader />
</columnHeader>
<contents>
<bc4j:input readOnly="true" />
</contents>
</bc4j:column>
</bc4j:columnStamp>
</bc4j:table>
</contents>
</bc4j:viewObjectScope>
</contents>
</bc4j:rootAppModuleScope>
In manual mode, users need to explicitly specify the attributes that they wish to render. Users also need to manually specify the association between user interface components and attribute types.
<bc4j:rootAppModuleScope name="EmpAppModule">
<contents>
<bc4j:viewObjectScope name="CurrentDeptEmpsVO">
<contents>
<bc4j:table name="emps" automatic="false">
<bc4j:keyStamp>
<bc4j:rowKey name="key" />
</bc4j:keyStamp>
<contents>
<bc4j:column attrName="Empno">
<columnHeader>
<bc4j:sortableHeader />
</columnHeader>
<contents>
<bc4j:textInput readOnly="true" />
</contents>
</bc4j:column>
<!-- other columns -->
<bc4j:column attrName="Emppic">
<columnHeader>
<bc4j:sortableHeader />
</columnHeader>
<contents>
<bc4j:image readOnly="true" />
</contents>
</bc4j:column>
</contents>
</bc4j:table>
</contents>
</bc4j:viewObjectScope>
</contents>
</bc4j:rootAppModuleScope>
At runtime, it is often useful to allow users to upload media content
into a database. Uploading content through a browser uses HTML's form
file upload field to allow users to pick which media file on their local
computer to upload to the server.
The HTML form element needs to be configured to use the POST
method
(rather than GET
)
and enctype="multipart/form-data"
so that the file content will be encoded correctly in
HTTP Post request sent to the server. For example, the uiXML <form>
element
and the event handler to support it should be specified like this:
<form method="post" usesUpload="true">
...
<form name="updateForm" usesUpload="true" method="post">
<contents>
<formParameter name="event"/>
<!-- layout the fields in two columns -->
<tableLayout>
<contents>
<bc4j:rootAppModuleScope name="EmpAppModule">
<contents>
<bc4j:viewObjectScope name="CurrentDeptEmpsVO">
<contents>
<bc4j:rowScope name="UpdateEmp">
<contents>
<bc4j:region automatic="true">
<bc4j:attrStamp>
<bc4j:messageInput/>
</bc4j:attrStamp>
</bc4j:region>
</contents>
</bc4j:rowScope>
</contents>
</bc4j:viewObjectScope>
</contents>
</bc4j:rootAppModuleScope>
</contents>
</tableLayout>
</contents>
</form>
...
<handlers>
<event name="apply">
<bc4j:findRootAppModule name="EmpAppModule">
<!-- establish the ViewObject scope -->
<bc4j:findViewObject name="CurrentDeptEmpsVO">
<!-- find the row by key, falling back on a new default
row if the key is not found -->
<bc4j:findRow name="UpdateEmp">
<bc4j:setRegion automatic="true"/>
<bc4j:commit/>
<bc4j:executeQuery/>
<!-- forward to the summary page -->
<ctrl:go name="showEmp" redirect="true"/>
</bc4j:findRow>
</bc4j:findViewObject>
</bc4j:findRootAppModule>
</event>
</handlers>
...
<form name="updateForm" usesUpload="true" method="post">
<contents>
<formParameter name="event"/>
<!-- layout the fields in two columns -->
<tableLayout>
<contents>
<bc4j:rootAppModuleScope name="EmpAppModule">
<contents>
<bc4j:viewObjectScope name="CurrentDeptEmpsVO">
<contents>
<bc4j:rowScope name="UpdateEmp">
<contents>
<bc4j:messageInput attrName="Empno"/>
<bc4j:messageInput attrName="Ename"/>
<!-- other attributes -->
<bc4j:messageFileUpload attrName="Emppic"/>
</contents>
</bc4j:rowScope>
</contents>
</bc4j:viewObjectScope>
</contents>
</bc4j:rootAppModuleScope>
</contents>
</tableLayout>
</contents>
</form>
...
<handlers>
<event name="apply">
<bc4j:findRootAppModule name="EmpAppModule">
<!-- establish the ViewObject scope -->
<bc4j:findViewObject name="CurrentDeptEmpsVO">
<!-- find the row by key, falling back on a new default
row if the key is not found -->
<bc4j:findRow name="UpdateEmp">
<bc4j:setAttribute name="Empno" paramName="Empno"/>
<bc4j:setAttribute name="Ename" paramName="Ename"/>
<!-- other attributes -->
<bc4j:setAttribute name="Emppic" paramName="Emppic"/>
<bc4j:commit/>
<bc4j:executeQuery/>
<!-- forward to the summary page -->
<ctrl:go name="showEmp" redirect="true"/>
</bc4j:findRow>
</bc4j:findViewObject>
</bc4j:findRootAppModule>
</event>
</handlers>
If a uiXML application displays interMedia content, the web.xml
file for that application needs to have the following configuration entries so that
the J2EE container can run properly:
<servlet>
<servlet-name>ordDeliverMedia</servlet-name>
<servlet-class>oracle.ord.html.OrdPlayMediaServlet</servlet-class>
<init-param>
<param-name>releaseMode</param-name>
<param-value>Stateful</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ordDeliverMedia</servlet-name>
<url-pattern>ordDeliverMedia</url-pattern>
</servlet-mapping>
oracle.ord.html.OrdPlayMediaServlet
is a pre-supplied Java servlet that
delivers interMedia content from a database to a browser. "ordDeliverMedia" is
its default servlet name and servlet mapping. "releaseMode" parameter is used to
specify the release mode of the servlet. Its value could be one of "Stateful",
"Stateless", or "Reserved". Please refer to BC4J documentation for more discussion
about release mode.
If a uiXML application needs to upload files to update interMedia objects in the database, the
web.xml
needs the following extra entry for oracle.cabo.servlet.BajaServlet
:
<init-param>
<param-name>oracle.cabo.servlet.io.FileUploadManager</param-name>
<param-value>oracle.cabo.data.jbo.servlet.io.OrdFileUploadManager</param-value>
</init-param>
oracle.cabo.servlet.io.FileUploadManager
parameter is used to specify a
custom class to handle HTTP POST file upload.
oracle.cabo.data.jbo.servlet.io.OrdFileUploadManager
is the interMedia
implementation of HTTP POST file upload handler. It parses the multipart stream and
sets browser uploaded files to interMedia objects.
When uploading content, it is important to manage both web server memory usage for browser file uploads and the temporary directory used to cache media content on the server during upload. This needs to be addressed because media files can often grow very large, and the server needs control over how to handle them.
The browser uploaded content will be cached in the server memory before the memory limit is reached. At that point, the content will be written to temporary files. These memory and file resources will be freed at the end of the upload operation, i.e. the HTTP request.
There are two servlet init parameters that specify the memory limit and
the directory for these temporary files: oracle.cabo.data.jbo.servlet.ord.HttpMaxMemory
and
oracle.cabo.data.jbo.servlet.ord.HttpTempDir
. They both belong to
oracle.cabo.servlet.BajaServlet
.
These two parameters are optional. The default value for
oracle.cabo.data.jbo.servlet.ord.HttpMaxMemory
is 102400 bytes. The default value for
oracle.cabo.data.jbo.servlet.ord.HttpTempDir
is the java.io.tmpdir
system property value.
For example:
<init-param>
<param-name>oracle.cabo.data.jbo.servlet.ord.HttpMaxMemory</param-name>
<param-value>1024</param-value>
</init-param>
<init-param>
<param-name>oracle.cabo.data.jbo.servlet.ord.HttpTempDir</param-name>
<param-value>D:/temp/ord</param-value>
</init-param>
This example specifies that, if the incoming uploaded content is bigger than 1024 bytes, the content will be stored as a temp file under the "D:/temp/ord" directory.
Here is a complete sample listing of a properly configured UIX interMedia application.
<web-app>
<description>Empty web.xml file for Web Application</description>
<servlet>
<servlet-name>uix</servlet-name>
<servlet-class>oracle.cabo.servlet.BajaServlet</servlet-class>
<init-param>
<param-name>oracle.cabo.servlet.pageBroker</param-name>
<param-value>oracle.cabo.servlet.xml.UIXPageBroker</param-value>
</init-param>
<init-param>
<param-name>oracle.cabo.servlet.io.FileUploadManager</param-name>
<param-value>oracle.cabo.data.jbo.servlet.io.OrdFileUploadManager</param-value>
</init-param>
<init-param>
<param-name>oracle.cabo.ui.UIExtensions</param-name>
<param-value>oracle.cabo.data.jbo.ui.JboUIExtension</param-value>
</init-param>
<init-param>
<param-name>oracle.cabo.data.jbo.servlet.ord.HttpMaxMemory</param-name>
<param-value>1024</param-value>
</init-param>
<init-param>
<param-name>oracle.cabo.data.jbo.servlet.ord.HttpTempDir</param-name>
<param-value>D:/temp/ord</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>ordDeliverMedia</servlet-name>
<servlet-class>oracle.ord.html.OrdPlayMediaServlet</servlet-class>
<init-param>
<param-name>releaseMode</param-name>
<param-value>Stateful</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ordDeliverMedia</servlet-name>
<url-pattern>ordDeliverMedia</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>uix</servlet-name>
<url-pattern>*.uix</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>uix</servlet-name>
<url-pattern>/uix/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<mime-mapping>
<extension>html</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
<extension>txt</extension>
<mime-type>text/plain</mime-type>
</mime-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>