More Information...................................................................................................................99Appendix A
2010-11-164
Preface
Preface
The ReportEngine Java developer guide helps you to customize web application using Java SDK.
1.1 What you can learn from this guide?
This guide describes the processes and procedures for creating web application using SAP
BusinessObjects Enterprise SDK and the ReportEngine SDK.
1.2 Who should use this guide?
This guide is intended for developers who are interested in developing web applications using SAP
BusinessObjects Enterprise SDK and the ReportEngine SDK.
1.3 What you should know?
To use the SAP BusinessObjects Enterprise SDK and ReportEngine SDK, you need a working knowledge
of the concepts of distributed computing systems, HTTP server technology, and JSP or .NET
development. You also need a basic knowledge of the products in the SAP BusinessObjects product
line. Familiarity with SAP BusinessObjects Enterprise is assumed.
1.4 Related documents
For more information on classes and interfaces of SAP BusinessObjects Enterprise SDK and
ReportEngine SDK, refer to the following guides:
•
SAP BusinessObjects Enterprise Java API Reference guide
2010-11-165
Preface
•
ReportEngine Java API Reference guide
For information on assembling and deploying web application, refer
Interactive Analysis ReportEngine SDK
guide.
Deploying the SAP BusinessObjects
1.5 List of APIs not functional from the SAP BusinessObject XI 4.0 release onwards
In SAP BusinessObjects XI 4.0 release, the Report Engine SDK does not support the following features:
•Drilling in Web Intelligence documents
•Building queries
•Document and report editing
The following public classes and interfaces are no longer functional from SAP BusinessObjects XI 4.0
onwards:
2010-11-166
Introduction to the ReportEngine SDK
Introduction to the ReportEngine SDK
The ReportEngine SDK is used to view Interactive Analysis and Desktop Intelligence documents. It is
also used to create and modify Interactive Analysis documents. The ReportEngine SDK is considered
as a component of SAP BusinessObjects Enterprise SDK as they are designed to work together. For
example, if you want to modify and view a Interactive Analysis document in SAP BusinessObjects
Enterprise, then you must use SAP BusinessObjects Enterprise SDK and ReportEngine SDK in an
integrated fashion.
You can use COM, Java, or .NET API interfaces to create web portals that access the back-end SAP
BusinessObjects Enterprise server. Custom application developed using this SDK has the same
functionality as Infoview since it is created with some of the same APIs.
2.1 Packages for customizing SAP BusinessObjects Enterprise
There are two packages for customizing SAP BusinessObjects Enterprise:
•SAP BusinessObjects Enterprise SDK
This package is called the platform package and provides platform functions of the SAP
BusinessObjects servers and document scheduling.
•ReportEngine SDK
This package plugs into SAP BusinessObjects Enterprise SDK. It provides functionalities of Interactive
Analysis ReportEngines.
2010-11-167
Introduction to the ReportEngine SDK
2.2 ReportEngine SDK in SAP BusinessObjects Enterprise environment
SAP BusinessObjects Enterprise is a framework of servers that facilitates enterprise-wide, web-based
management and distribution of reports. Web applications can access the functionality of SAP
BusinessObjects Enterprise through APIs provided by the SAP BusinessObjects Enterprise SDK and
ReportEngine SDK. For detailed information on SAP BusinessObjects Enterprise, see the
The ReportEngine SDK enables you to create and modify Interactive Analysis and Desktop Intelligence
reports. These report modification services are provided by the ReportEngine server. For more information
about SAP BusinessObjects Enterprise servers, see the
Guide
.
The diagram below illustrates the relationship between the ReportEngine SDK and other SAP
BusinessObjects Enterprise components,
.
SAP BusinessObjects Enterprise Administrator's
SAP
2010-11-168
Introduction to the ReportEngine SDK
2010-11-169
Introduction to the ReportEngine SDK
2010-11-1610
Workflow of ReportEngine SDK application
Workflow of ReportEngine SDK application
All applications that use ReportEngine SDK do not have the same features. But all typically provide
features for listing and viewing documents contained in the SAP BusinessObjects Enterprise Central
Management System (CMS).
3.1 Application essentials
Every application that uses ReportEngine SDK has to perform common tasks such as importing the
appropriate packages, and creating and managing the user's SAP BusinessObjects Enterprise session
(login).
Every application has to take user profiles into account and ensure that errors are handled properly.
See User rights for categories and folders and User preferences.
3.2 Document management
Document management features include listing the documents that the current user can view depending
on user's rights. It allows the user to browse and manage categories and folders used to organize
documents.
Document management also include features such as saving and scheduling documents.
3.3 Viewing reports
An application that allows to view documents can display them using the default DHTML format. It is
easy to extend the functions to handle documents that contain prompts, and to provide drilling functions.
These extended functions are handled when a document is refreshed.
The viewing features depends on the type of document opened. The report-viewing part of the application
should include routines for viewing reports in the following document types:
2010-11-1611
Workflow of ReportEngine SDK application
•Interactive Analysis (*.wid)
•other document types, for example Adobe Acrobat, Microsoft Excel or XML format.
See Viewing reports for a full listing of available formats.
3.4 Formatting documents
Formatting documents involves creating and positioning the elements of a report (blocks, sections, and
cells) in the appropriate report structure. Using ReportEngine SDK you can build reports from scratch.
ReportEngine SDK includes classes for controlling report page decoration (fonts, colors, headers, and
footers) and layout.
3.5 Open document workflow
The following diagram shows the workflow for opening a document.
The document contains data that is retrieved from the data source (universe). Each document is identified
by an unique ID which is required to open a document.
3.6 Refresh document workflow
The following diagram shows the workflow for refreshing a document.
2010-11-1612
Workflow of ReportEngine SDK application
The document must be refreshed to get the latest information from the data source. The refresh action
requires prompt information if the document contains prompts, and context information if the document
contains contexts.
2010-11-1613
Workflow of ReportEngine SDK application
2010-11-1614
Setting up development environment
Setting up development environment
This section describes how to set up a development environment for web application based on
ReportEngine SDK in a Java environment.
4.1 Installing ReportEngine SDK components
The ReportEngine SDK components are added to the development machine when SAP BusinessObjects
Enterprise is installed on the system. To develop a custom ReportEngine SDK application it is necessary
to connect to a running SAP BusinessObjects Enterprise server. However, the development environment
need not be on the same machine as the SAP BusinessObjects Enterprise Server.
To install the ReportEngine SDK components on a development machine, perform the following steps
:
1.
Run SAP BusinessObjects Enterprise installer.
2.
Choose the Setup language and click OK.
3.
Click Next on the "BusinessObjects Enterprise XI 3.1 Installation Wizard" window.
4.
Select the I accept the License Agreement in the "License Agreement" panel.
5.
Click Next.
6.
Enter your corporate information and keycode.
7.
Click Next.
8.
Click Next.
9.
In the "Install Type" window, select Custom or Expand Install button.
10.
Specify the destination folder in the "Destination Folder" text box.
11.
Click Next.
12.
Deselect all BusinessObjects Enterprise Features.
13.
Enable the Developer Components.
To install J2EE components only, deselect the SDK products feature and install the Java features
sub-component.
14.
Click Next.
2010-11-1615
Setting up development environment
15.
Click Next.
This installs all components necessary to develop custom Business Objects applications; Java libraries
are installed and registered correctly.
4.2 Setting up the Java environment
To setup the ReportEngine Java environment, refer the following sections:
•Setting up the Eclipse framework
•Project Setup
4.2.1 Setting up the Eclipse environment
Eclipse is an Integrated Development Environment (IDE) which provides a universal toolset for application
development. Eclipse is an open development platform and can be downloaded from the eclipse web
site for free of cost.
To create a Java web-based application, you must have an application server and Java Development
Kit (JDK) installed on the machine. By default, Apache Tomcat application server is installed along with
SAP BusinessObjects Enterprise installation. Hence, an example on creating a dynamic web project
is explained considering Apache Tomcat as an application server.
4.2.2 Project Setup
It is recommended to create a dynamic web project using Eclipse. It has the following advantages:
•External jars and other Eclipse projects can be included in the working project.
•Easy to export a war file which can be deployed in any application server.
•Easy to run the application code.
The Web project contains the JSP files, images and various web components in a structured manner.
The WEB-INF, lib, classes and other directories which are required to create a web application will be
predefined. This makes the coding simpler.
2010-11-1616
Setting up development environment
4.2.2.1 Creating a dynamic web project
The following are the pre-requisites for creating a web application:
•Eclipse must be installed and configured.
•Apache Tomcat application server must be installed.
•Java Development Kit (JDK) must be installed and configured.
1.
Launch Eclipse by selecting a workspace.
2.
In the Package Explorer panel, right-click, select New and click Project.
"Select a Wizard" window appears.
3.
In the list box, expand Web and select Dynamic Web Project.
4.
Click Next.
"Dynamic Web Project" window appears.
5.
Enter the "Project Name".
6.
Under "Target Runtime", click New.
"New Server Runtime" window appears.
7.
Under "Select the type of runtime that you want to define:", expand Apache and select the runtime.
8.
Click Next.
"Tomcat Server" window appears.
9.
Under "Tomcat installation directory", click Browse and select the Tomcat installation directory.
10.
Under JRE, click Installed JREs.
"Installed JREs" window appears.
11.
Click Add, enter "JRE name", "JRE home directory " and click OK.
12.
In the "Installed JREs" window, select the JRE and click OK.
The <BOProductName>Interactive Analysis SDK package
log4j.logger.com.businessobjects.rebean.ReportEngines allows you to integrate trace messages
from your own application with those generated by the SAP BusinessObjects servers and
<BOProductName>Interactive Analysis SDK.
The following sections describe the REBean logging in more details:
•"Trace Levels"
•"Activating logging by editing the configuration files"
•"Activating logging by using the default settings"
•"Activating logging while Tomcat is running"
4.3.1.1.1 Trace Levels
The following table shows the trace levels available through the above mentioned trace systems:
2010-11-1619
Setting up development environment
Provides messages onTrace Level
•helper classes
DEBUG
•calls from REBean to the report engine server
•JHSAL activity
•entry of each JSP
INFO
WARN
ERROR
•calls to the methods exposed by REBean
•potentially harmful situations
•non-fatal exceptions
•exceptions that stop the execution of applica-
FATAL
tion
4.3.1.1.2 Activating logging by editing the configuration files
To activate logging, you must edit the webi.properties file. When you change this file, you need to restart
Tomcat for your changes to take effect.
To activate the logging system, add the following lines to the webi.properties configuration file:
Where LEVEL can be one of: DEBUG, INFO, WARN, ERROR, or FATAL. This automatically selects
the log4j logging system and sets the trace level to LEVEL. If there is no log4.properties file,
log4.properties.todo is generated.
system is one of: Log4jLogger (log4j), or StandardLogger (debugdiag)
This activates logging, selects the system logging system, and sets the trace level to LEVEL. If there
is no configuration file for the logging system a .todo file is generated.
4.3.1.1.3 Activating logging by using the default settings
To activate the logging system using the default settings:
1.
Add the following line to the webi.properties configuration file:
Trace=1
2.
Start, or restart Tomcat.
2010-11-1620
Setting up development environment
This activates logging, by default the log4j logging system is selected, and the trace level is set to
INFO. If there is no log4j.properties file, log4j.properties.todo is generated.
4.3.1.1.4 Activating logging while Tomcat is running
To activate logging while Tomcat is running, put the following code in a file called traces.jsp and
put the file in the same folder at the InfoView files. Then, to activate logging, open traces.jsp in a
web browser and select the options (logging system, and trace level) you want.
The following is an example of the traces.jsp file:
Example: Activating logging while Tomcat is running
4.3.1.2 Configuring the Jakarta log4j logging system
The Jakarta log4j logging system uses a configuration file called log4j.properties. This file must be
present in the classes directory of the web application, for example, webapps\wijsp\WEB-INF\classes.
If the configuration file is not present log4j.properties.todo is created in the bin folder of the application
server, however you should move this file to the classes directory for your web application (and remove
the "todo" from the file name) so you can have one configuration file for each application.
This logging system is delivered with the SAP BusinessObjects platform. It is installed in
$INSTALLDIR\classes. See also http://jakarta.apache.org/log4j/docs/index.html for further explanation
of the configuration options for this tool.
The following sections describe the Jakarta log4j logging system in more details:
•Setting the trace level
•Setting the trace mechanism
•Setting the trace output
•Specifying the trace level for individual classes
4.3.1.2.1 Setting the trace level
You set the trace level in log4j.properties. The possible levels are DEBUG, INFO, WARN, ERROR,
and FATAL.
The trace level setting in log4j.properties takes precedence over the trace level setting in webi.properties.
4.3.1.2.2 Setting the trace mechanism
You set the trace output mechanism in log4j.properties. Possible output mechanisms are: file, console
(stdout), or a socket.
4.3.1.2.3 Setting the trace output
You can set the output format in log4j.properties. The following table shows the formatting tokens you
can use.
2010-11-1622
Setting up development environment
Adds this to the traceThis token
date%d
thread%t
trace level%p
the name of the logger%c
time since the trace system was initialized%r
thread content, for example, the session ID%x
the message%m
4.3.1.2.4 Specifying the trace level for individual classes
You can specify the trace level for a package or a class.
For example, if the root trace level is DEBUG, but you do not want to see the trace for the REBean
package, add the line log4j.logger.com.businessobjects.rebean.wi=WARN to
log4j.properties.
Similarly, you can exclude the trace for the ReportEngine interface with log4j.logger.com.busi
nessobjects.rebean.wi.ReportEngine=WARN
log4j.properties
Example: log4j.properties
The following lists the contents of log4j.properties. In this example, the root trace level is set to
DEBUG, and traces from the Report interface are excluded.
4.4 Configuring ReportEngine using webi.properties
You can configure individual ReportEngine SDK or viewer applications such as InfoView to improve
their efficiency on application server on which they have been deployed. The purpose of this chapter
is to tell you how to improve SAP BusinessObjects Enterprise application efficiency.
4.4.1 What is webi.properties?
Each ReportEngine web application can have a webi.properties file. For SAP BusinessObjects Enterprise
applications this file is optional. The webi.properties file is located in the WEB-INF\classes subdirectory
of the <BOProductName>AnalyticalReporting. For example, if you have deployed InfoView on a Tomcat
application server the webi.properties file would be found in the following directory:
The webi.properties file is a plain text file containing variables used to tune the individual
<BOProductName>Web Intelligence web application. The variables defined in the webi.properties file
are taken in to account when your <BOProductName>Interactive Analysis server starts up. To change
variable settings in webi.properties, Business Objects recommends that you do the following:
1.
Navigate to the classes subdirectory in your <BOProductName>Interactive Analysis web application,
that is to say <MyWebIntelligenceApp>/WEB-INF/classes.
2.
Make a copy of the webi.properties file. This copy is to stay in the
<MyWebIntelligenceApp>/WEB-INF/classes subdirectory as a backup.
2010-11-1624
Setting up development environment
3.
Copy webi.properties to a temporary directory.
4.
Edit webi.properties using text editor, set the value of the variables as required.
5.
Replace <MyWebIntelligenceApp>/WEB-INF/classes/webi.properties with your updated version.
6.
Restart the server.
A comprehensive list of variables to update can be found in the next section.
4.4.3 Configuration Options
TEMP_DIR
The directory where temporary
files generated by <BOProductName>Interactive Analysis are
stored.
Default ValueDescriptionVariable Name
same as the Java temporary
directory
XML_TRANSFORMER
CHUNK_SIZE
FAILOVER_SIZE
MAX_HEAP_SIZE
Trace
The parser used for XML translation.
The size of binary or character
object sent between the client
browser and the <BOProductName>Interactive Analysis server.
Control the maximum number of
document states kept in memory.
Prevent the web application from
consuming all the heap of the
Java Virtual Machine.
Set the application to trace internal <BOProductName>Interactive Analysis calls.
The following variables can be used to tune web applications:
Note:
For application servers running with the Java Virtual Machine 1.4 and above, runtime.maxMemory is
used to set the MAX_MEMORY variable internally. This ensures that your <BOProductName>Interactive
Analysis application does not consume the Java Virtual Machine heap.
Sets the limit of undo actions
possible for DocumentInstance
objects.
Set to 0 for no limit for file persistence and token are storage until
memory reaches
FAILOVER_SIZE.
Default ValueDescriptionVariable Name
11
In order to optimize resources on the Interactive Analysis server, the STORAGE_TOKEN_STACK_SIZE
parameter is used to limit the size of the stack by limiting document serialization. For the end user, this
means the number of undo actions that can be done.
The default value of STORAGE_TOKEN_STACK_SIZE is 10, the same as the FAILOVER_SIZE variable.
•If STORAGE_TOKEN_STACK_SIZE =0, then there is no limit for file persistence and token are
stored into memory until reaching FAILOVER_SIZE. If failover happens, the maximum number of
DocumentInstance objects in the storage manager will fail over to a backup application server.
•If STORAGE_TOKEN_STACK_SIZE <= FAILOVER_SIZE, then there is no file persistence.
•If STORAGE_TOKEN_STACK_SIZE > FAILOVER_SIZE up to (STORAGE_TOKEN_STACK_SIZE
minus FAILOVER_SIZE), instances are stored in file system.
The memory footprint for a document state that is higher than the value of
STORAGE_TOKEN_STACK_SIZE in the stack is deleted. If a client tries to use an out of stack token
to access a document state the ReportEngine will throw an exception. You can retrieve the stack size
programmatically and validate storage tokens using:
This section describes the procedures to develop a custom web application using ReportEngine SDK.
5.1 Application Essentials
5.1.1 Overview
Before providing viewing, reporting, and editing functions, the ReportEngine SDK applications need
to perform basic tasks, such as referencing the appropriate package and creating a BusinessObjects
Enterprise session for the user.
This section covers the essential concepts and tasks, which all the applications that customize
BusinessObjects Enterprise must use.
5.1.2 "Hello World"
The simplest application you can write with SAP BusinessObjects Enterprise SDK is the one that creates
a SAP BusinessObjects Enterprise session which provides log in and log out functions.
This is the basis for building much more sophisticated applications that provide functions to list, view
and create documents, and attach them to hierarchical categories.
2010-11-1627
Developing web application using ReportEngine SDK
This application gathers login details from the user, and sends the details to another page which uses
SAP BusinessObjects Enterprise SDK to open a SAP BusinessObjects Enterprise session. If the session
is successfully created, the application displays a "Hello World" message and the option to log out.
When the user clicks the logout link, the application closes the user's SAP BusinessObjects Enterprise
session with SAP BusinessObjects Enterprise SDK and displays the first page again.
Each page that uses SAP BusinessObjects Enterprise SDK must:
•reference SAP BusinessObjects Enterprise SDK
•create or reference an IEnterpriseSession object
•create or reference an IInfoStore object
See "Implementing "Hello World"" for code that implements this application.
5.1.2.1 Referencing SAP BusinessObjects Enterprise SDK
Referencing SAP BusinessObjects Enterprise SDK gives your web application access to the SAP
BusinessObjects Enterprise platform functions exposed by the SDK.
Note:
You must use SAP BusinessObjects Enterprise SDK prior to using ReportEngine SDK.
To develop a Java application SAP BusinessObjects recomments that you add all libraries found in the
<BusinessObjectsHome>\Tomcat55\webapps\AnalyticalReporting\WEB-INF\lib into
the WEB-INF\lib directory of your JSP project.
5.1.2.1.1 Referencing SAP BusinessObjects Enterprise SDK
To reference SAP BusinessObjects Enterprise SDK, import the SAP BusinessObjects Enterprise
packages.
2010-11-1628
Developing web application using ReportEngine SDK
Example: Referencing SAP BusinessObjects Enterprise SDK
To import SAP BusinessObjects Enterprise SDK packages, add the following line to pages that use
the packages.
You need to include this line in every page that uses SAP BusinessObjects Enterprise SDK.
5.1.2.2 Creating a new user session
In SAP BusinessObjects Enterprise SDK, the ISessionMgr allows user to log in to the SAP
BusinessObjects Enterprise server and create a session. Session information is stored in the IEnter
priseSession object returned by logon method. Every session has a corresponding IEnterpris
eSession object which is used to access the ReportEngine SDK.
5.1.2.2.1 Creating an ISessionMgr object
To create a user session for an application that uses SAP BusinessObjects Enterprise SDK, you must
first instantiate a new ISessionMgr object.
Every user of InfoView requires a SAP BusinessObjects Enterprise session for logging in and using
the system. The SAP BusinessObjects Enterprise session represents the user's current interaction with
SAP BusinessObjects Enterprise. A user's SAP BusinessObjects Enterprise session provides access
to the user's details, and objects that are subject to the rights of the user, for example, the list of universes
that the current user can use to create documents.
2010-11-1629
Developing web application using ReportEngine SDK
You must create a SAP BusinessObjects Enterprise session for the user which is a key part of the log
in and authentication process.
To create a session for a user:
1.
Get the user's login information:
•name
•password
•the Central Management System (CMS), that the user wants to log into
•authentication type (Enterprise, LDAP, winAD)
2.
Establish a valid SAP BusinessObjects Enterprise session for the user.
5.1.3.1 Getting login information
The simplest way to get a user's login information is to use an HTML form in which the user enters the
name, the password, the CMS, and the auth type. When the user submits the form, the values for the
fields are passed through the query-string to a page that processes the values.
Example: HTML form for gathering a user's login information using Java
When the user enters login information and clicks the Login button, the values of the fields are passed
to Login.jsp in the query string parameters. The method attribute of the form is set to POST, and therefore
these values will not be visible in the URL.
2010-11-1630
Developing web application using ReportEngine SDK
5.1.3.1.1 Authentication
The way you monitor passwords depends on how SAP BusinessObjects Enterprise passwords are set
up by the SAP BusinessObjects Enterprise system administrator.
There are two settings available to the system administrator which you can use as the basis for the
login procedure in your own application:
•Enterprise Mode
This mode requires the user to submit user name and password which are unique to SAP
BusinessObjects Enterprise (and can be different from their network name/password combination).
•LDAP Mode
This mode requires the user to submit user name and password which are stored on a corporate
LDAP server.
•WinAD Mode
This mode requires the user to submit user name and password which are stored on a Windows
Authentication Server.
For more information on authentication in Windows, see the
Administrator's Guide
.
SAP BusinessObjects Enterprise
5.1.3.2 Establishing a valid SAP BusinessObjects Enterprise user's session
To establish a valid SAP BusinessObjects Enterprise user's session:
1.
Create an IEnterpriseSession object for the user.
2.
If the IEnterpriseSession object is valid, store this object in the user's session attributes.
3.
Create an IInfoStore object and store it in the user's session attributes.
These steps are followed by redirecting the user to an appropriate page: a welcome page or back
to the login page, depending on the validity of the session.
Example: Establishing a session
The following code fragment illustrates how to establish a SAP BusinessObjects Enterprise session.
5.1.3.3 Retrieving and Closing SAP BusinessObjects Enterprise session
Once you have established a valid SAP BusinessObjects Enterprise session for the user, you can
retrieve it from the user's session attributes.
To close a session, use IEnterpriseSession.logoff() .
Closing a session is important:
•It frees the resources held by the user's SAP BusinessObjects Enterprise session.
•It forces other users to start their own sessions rather than just taking over an existing session.
Note:
See logout.jsp for an example of how to close a SAP BusinessObjects Enterprise session.
5.1.3.4 SAP BusinessObjects Enterprise session time-out
The time-out of SAP BusinessObjects Enterprise SDK session is the life time of the EnterpriseSession
object. The session is destroyed when the object is destroyed.
SAP BusinessObjects recommends that you store the users IEnterpriseSession object in the
application server session objects. In this way, the user session has the exact time out as the Application
server session.
5.1.4 Implementing "Hello World"
Following is an implementation of the Hello World application discussed on "Hello World". To run this
application you need to have installed SAP BusinessObjects Enterprise and established a Business
Objects Central Management System. For more information, see the
Installation and Configuration Guide
for Windows or UNIX.
SAP BusinessObjects Enterprise
2010-11-1632
Developing web application using ReportEngine SDK
In this implementation, index.jsp displays a form which collects the user's login information which is
passed to login.jsp. Login.jsp attempts to create a session and IInfoObject for the user. If the
operation is successful, login.jsp redirects to home.html which displays the "Hello World" message and
a link to logout.jsp. When the user clicks the logout link, logout.jsp closes the session and displays
index.jsp again.
5.1.4.1 index.jsp
index.jspx is the default entry point for a SAP BusinessObjects Enterprise user.
This page is opened when the user clicks Login in the form LoginForm. The user name and password
used for the login are passed from the HTML form in the query string parameters Name and Pass.
Users can set their InfoView and ReportEngine viewing options using the Preferences page in InfoView
or SAP BusinessObjects Enterprise SDK.
When designing a ReportEngine SDK application you must take this into account. For example, if a
user wants to use the Java version of the Report Panel for creating and editing documents, then you
need to design your application so that it can display the Java Report Panel rather than the DHTML
Report Panel.
5.1.5.1 Accessing InfoView user preferences
With SAP BusinessObjects Enterprise SDK you can get, set and add new preferences in a user's profile.
Standard preferences and possible settings are:
2010-11-1635
Developing web application using ReportEngine SDK
Table 5-1: Standard preferences and possible settings
MeaningPossible ValuesVariable Name
View documents in PDF format.P
webi_view
webi_panel
DOCUMENT_WIStartNewDrill
I
H
java
html
duplicate
existing
View Documents in Interactive
format.
View Documents in DHTML format.
(default)
Create documents using the
Java Report Panel.
(default)
Create documents using the
HTML Report Panel.
Start the drill action in a duplicate report.
Start the Drill action in the current report. (default)
DOCUMENT_WIPromptDrill
OutScope
Prompt if drill requires additional
N
data.
(default)
Y
Do not prompt if Drill requires
additional data.
2010-11-1636
Developing web application using ReportEngine SDK
MeaningPossible ValuesVariable Name
Prompt if drill requires additional
N
data.
(default)
DOCUMENT_WISyncDrillBlocks
N
Synchronize Drill on report
blocks.
(default)
Y
Do not Synchronize Drill on report blocks.
Show the Drill bar.N
DOCUMENT_WIDrillBar
Hide the Drill bar.
Y
(default)
Note:
Other applications can have their own user settings which are stored in the user profile. For more
information, see Adding custom options to a user's profile.
5.1.5.1.1 Getting a user's InfoView preferences
To read the value of user's option:
1.
Get the current user's IUser object using an IInfoStore query.
2.
Get the "desktopsettings" profile string.
3.
Convert the profile string to a Map for easy manipulation and printing.
The following code shows how to retrieve user's SAP BusinessObjects Enterprise preferences and
print them to an HTML response stream.
Example: Printing user's preferences
<%!
//Return a string containing a user's Interactive Analysis Preferences
String getWebiPrefs(IInfoStore iStore, int uId){
The following code fragment shows how to use the functions declared above to print a user's SAP
BusinessObjects Enterprise preferences to an HTML stream.
Example: Printing SAP BusinessObjects Enterprise preferences to an HTML stream
The functions getWebiPrefs and webiPrefsToMap are declared in the Printing a user's preferences
example.
5.1.5.1.3 Adding custom options to a user's profile
To add custom options to user's profile:
1.
Get user's preferences.
2.
Set the custom option with Map.put .
When you set an option that does not exist in the user profile, Map.put creates a new option and
sets it to the value you specify.
3.
Convert the Map to a String.
4.
Update the user profile with IInfoStore.commit .
The following code fragment sets a custom preference
2010-11-1639
Developing web application using ReportEngine SDK
Example: Adding a new preference to a user's profile
<%
//Add a custom Interactive Analysis preference using functions defined in the previous examples
int userID = myIEnterpriseSession.getUserInfo().getUserID();
String prefs = getWebiPrefs(myIInfoStore, userID);
Map prefsMap = webiPrefsToMap(prefs);
prefsMap.put( "MyPreference", "tea");
setWebiPrefs(iStore, webiPrefsToSting(prefsMap), userID);
%>
Note:
The functions getWebiPrefs and webiPrefsToMap are declared in the Getting a user's InfoView
preferences example .
5.1.6 Exceptions generated by the SAP BusinessObjects Enterprise SDK
SAP BusinessObjects Enterprise SDK generates the exceptions of the type REException.
Depending on the cause of the exception, the ReportEngine SDK generates exceptions of the following
type:
•CommunicationException
•ConfigurationException
•CustomSortException
•DSObjectSynchroException
•FilterConditionException
•NotImplementedException
•QueryException
•InvalidParameterException
•ReportException
•ServerException
•UnsupportedFeatureException
Exceptions and their descriptions are listed in the online reference documentation.
Note:
•All exception classes listed above are subclasses of the REException class. SAP BusinessObjects
recommends to use REException.getCode() when testing the code.
•You can return localized error messages by calling REException.getLocalizedMessage().
2010-11-1640
Developing web application using ReportEngine SDK
5.1.7 Working with the ReportEngine SDK
All applications that view, edit or format Interactive Analysis documents must:
•reference ReportEngine SDK
•retrieve the ReportEngines service
•retrieve the ReportEngine instance
This links the ReportEngine and platform packages.
•close the ReportEngines object
Note:
You can use the ReportEngine SDK to:
•View, refresh, fill prompt, fill context, drill, edit query, save and format Interactive Analysis documents.
5.1.7.1 Referencing ReportEngine SDK
Referencing the ReportEngine packages gives your web application an access to the ReportEngine
SDK functions.
ReportEngine SDK allows users to work with both the Interactive Analysis documents. Use the
ReportEngines factory object to retrieve the ReportEngine instance, necessary to open the document
type required.
If the web application uses J2EE it must reference REBean.
Example: Referencing the ReportEngine SDK
To import the REBean package, add the following line to the JSP pages that use REBean.
You need to include this line in every JSP page that uses REBean classes.
5.1.7.2 Creating a ReportEngine object
2010-11-1641
Developing web application using ReportEngine SDK
To create a ReportEngine object for an application that uses ReportEngine SDK, retrieve the Re
portEngines object from the user's IEnterpriseSession. Using the ReportEngines object youcan retrieve a ReportEngine instance to open either Interactive Analysis documents.
Example: Instantiating a ReportEngine object
To instantiate the ReportEngine object, add the following lines to a page of the web application that
uses the reporting features of the ReportEngine SDK.
To close a BusinessObjects Enterprise session, you must close a ReportEngines instance when you
have finished with it. To close a ReportEngines instance use ReportEngines.close(). This method
2010-11-1642
Developing web application using ReportEngine SDK
deallocates the memory assigned to the object and must be called before you call IEnterpriseSes
sion.logoff() .
5.2 Document Management
5.2.1 Overview
Two key parts of a typical ReportEngine SDK application are:
1.
Listing the documents that the user can view.
2.
Depending on the user's rights, allowing the user to browse and manage categories and folders
used to organize the documents.
This section explains how to open, list, and work with documents.
5.2.2 Document types
With BusinessObjects Enterprise SDK, you can work with the following document types:
•Interactive Analysis documents
•Crystal Reports documents
•third-party documents, for example Microsoft Excel (.xls), and Adobe Acrobat (.pdf) files
Working with the Interactive Analysis documents using the ReportEngine SDK
Using ReportEngine SDK you can do everything that Interactive Analysis users can do with Interactive
Analysis documents:
•view as DHTML
•view as PDF
•view as Excel
•view as XML
•refresh
•create
2010-11-1643
Developing web application using ReportEngine SDK
•categorize
•delete
•drill
•save
•schedule
•send
5.2.3 Document state: storage tokens
Storage tokens represents a state of a document at a particular stage, each time a document is edited.
For example, the document state changes when the document is refreshed.
Storage tokens are used to:
•Retrieve the document state from page to page.
•Simulate an undo action in a customized application.
5.2.3.1 Storage token life cycle
ReportEngine SDK generates a storage token:
•when you open a document.
•when the microcube contents are modified or formatted.
When you open a document, ReportEngine SDK creates a DocumentInstance object that has a
storage token. ReportEngine SDK also creates a temporary state that contains information about the
document's current state.
2010-11-1644
Developing web application using ReportEngine SDK
A storage token is self descriptive with respect to the type of ReportEngine required to open the
associated document. This means that you need not check the document type before opening it.
As the document changes state through the execution of JSP files, the storage token changes too, and
more temporary states are created representing the document's states.
You can retrieve the maximum number of storage tokens that can be created as a document changes
state programmatically and validate that a storage token is valid by calling ReportEngine.getStorageTokenStackSize()and ReportEngine.IsStorageTokenValid respectively.
The ReportEngine SDK generates a new storage token and the corresponding set of temporary files
at the following triggers:
SDK TriggersUser interface Triggers
refreshing the document
drilling
creating and editing a document
applying new formats
calling DocumentInstance.getView
modifying the DrillPath
calling DataProvider.getResult
calling DataProvider.runQuery
opening a documentrunning a query
Note:
Setting a password, and filling in a prompt does not generate a new token directly. However, a new
storage token is generated when you commit the change using DocumentInstance.getView .
The following diagram shows how storage tokens change according to triggers in the user interface
and the object model. It shows how the storage tokens are passed between the web pages. It refers
the file states stored in memory that can be used to reconstruct the DocumentInstance object using
ReportEngine.getDocumentFromStoratagetoken method. In the diagram below, this method
name is shortened to "get doc".
Using the storage token as an identifier for a document state, you can restore the document to any of
its saved states.
2010-11-1645
Developing web application using ReportEngine SDK
5.2.3.2 Advantages of storage tokens
The advantages of storage tokens are as follows:
Performance
Using storage token, you can quickly switch between the document states. It also helps to optimize the
memory usage.
Lifetime
A storage token in the file system lasts as long as the ReportEngines object used to create Re
portEngine instance exists. Business Objects recommends you to store a ReportEngines object in
2010-11-1646
Developing web application using ReportEngine SDK
the session object once it is created and retrieve it again as required, for document storage tokens to
be valid throughout an application.
Browser navigation: back and forward
After progressing through several document states, users can go back and forward in their browser to
a previous document state and continue working from that state.
Undo mechanism
You can build an undo mechanism by passing the storage token from the previous action performed
on the document to the next web page.
5.2.4 Organizing documents in categories and folders
In InfoView, categories and folders are used to classify documents in the Central Management System.
Documents organized in the hierarchical category and folder structures are easy to find for users. A
user can save a document to selected categories and folders. A document can be assigned to one or
more public or personal categories.
Using the BusinessObjects Enterprise query mechanism you can navigate a category or folder hierarchy
and retrieve IInfoObjects containing the individual categories and folders. These enable you to:
•create, rename and delete categories and folders
•get the details of categories and folders
5.2.4.1 User rights for categories and folders
A System Administrator can set the rights to a user or group on categories and folders using
BusinessObjects Enterprise Central Management Console. User rights settings are updated in the
Advanced Rights page of the InfoView section for BusinessObjects Enterprise Applications of the Central
Management Console.
The following table lists an InfoView user's possible rights.
2010-11-1647
Developing web application using ReportEngine SDK
Variable NameInfoView Advanced Right
User can change preferences
User can move and copy objects, create shortcuts
and add object to the favorites folder.
User can use InfoView simple search
User can use InfoView advanced search
User can use InfoView filter feature
User can view favorites folder
User can view inbox contents
User can create categories
User can assign categories to users or groups
CeInfoViewRightID.PREFERENCE
CeInfoViewRightID.ORGANIZE
CeInfoViewRightID.SIMPLESEARCH
CeInfoViewRightID.ADVANCEDSEARCH
CeInfoViewRightID.FILTER
CeInfoViewRightID.FAVORITES
CeInfoViewRightID.VIEWINBOX
CeInfoViewRightID.CREATECATEGORIES
CeInfoViewRightID.ASSIGNCATEGORIES
User can send documents to users and groups
User can create dashboards
User can create folders
CeInfoViewRightID.SENDDOCUMENTS
CeInfoViewRightID.CREATEDASHBOARDS
CeInfoViewRightID.CREATEFOLDERS
A list of a user's rights over an object in the IInfoStore can be recovered by retrieving the user's
ISecurityInfo object for a certain BusinessObjects Enterprise application.
Example: Validating if a user has the right to create categories
This code fragment shows how to validate if a user has the right to create categories.
IInfoObjects appObjects = iStore.query( query);
if (appObjects.size() > 0)
infoView = (IInfoObject )appObjects.get(0);
if (infoView != null){
ISecurityInfo secInfo =
infoView.getSecurityInfo();
if (secInfo.checkCustomRight(
CeInfoViewRightID.CREATECATEGORIES,
infoView.getKind()))
{
...
}
}
}catch (Exception exc){
...
}
%>
Note:
•Before trying to manage categories, check that the user who started the session has an appropriate
rights.
•A list of rights for other BusinessObjects Enterprise applications can be found by changing the
CeKind being searched for. For example, to search for a user's Interactive Analysis rights, the query
string would include CeKind.WEBINTELLIGENCE in the place of CeKind.INFOVIEW.
5.2.4.2 Navigating categories and folders
Categories and folders in a Central Management System are represented as a tree. Personal and Public
are root nodes for categories. Home is the root node for folders.
To access the category or the folder trees, query the repository to retrieve the ID of the parent node for
categories or folders. Use this ID to navigate the child nodes.
Example: Traversing the category tree recursively
The following example shows functions that use BusinessObjects Enterprise SDK to recover the ID
of the parent folder for a user's personal categories. Using this ID, a bulleted list containing the
hierarchical structure of the user's personal categories is generated.
<%! //Return the ID of a specific folder
public int getFolderParentId(IInfoStore iStore, int userID,
String kind){
int FolderID = 0;
IInfoObjects folders = null;
String query = "SELECT SI_PARENTID FROM CI_INFOOBJECTS"
+ " WHERE SI_KIND='" + kind + "'"
+ " AND SI_OWNERID=" + userID;
For an example of how to list the documents in a folder, see Displaying document lists.
5.2.4.3 Retrieving Inbox and favorites folder
Each BusinessObjects Enterprise user has unique personal directories. The Inbox and the Favorites
directories contain documents sent to a specific user or saved for personal rather than corporate use.
To list the contents of these folders, you must retrieve the ID for each user's personal directories. Once
the root directory ID is retrieved, you can list and navigate the contents in the same way corporate
folders are navigated.
2010-11-1650
Developing web application using ReportEngine SDK
Example: Retrieving a user's Inbox and Favorites folder IDs
The following example shows functions that use BusinessObjects Enterprise SDK to retrieve the ID
of the parent folder for a user's Inbox and Favorites folders.
<%!
//Retrieve the ID for any type of personal folder
public int getFolderId(IInfoStore iStore, int userID,
throw new Error("Failed to add the object.");
}
return objectID;
}
%>
The following code fragment shows how to use the functions declared above to create a new personal
category and a new folder.
<%//How to use this function
//Create a new personal category
addFolderOrCategory(iStore, categoryParentID,
"Category Name", "Keywords",CeKind.PERSONALCAT);
//Create a new personal folder
addFolderOrCategory(iStore, categoryParentID,
"Folder Name", "Keywords", CeKind.FOLDERS);
//How to use this function
//Create a new personal category
addFolderOrCategory(iStore, categoryParentID,
"Category Name",
"Keywords",CeKind.PERSONALCAT);
//Create a new personal folder
addFolderOrCategory(iStore, categoryParentID,
"Folder Name", "Keywords", CeKind.FOLDERS);%>
5.2.4.5 Moving and renaming categories and folders
You can move categories and folders from one parent to another using the IInfoObject.setParen
tID()method . You can rename categories and folders using the IInfoObject.setTitle()method
.
2010-11-1652
Developing web application using ReportEngine SDK
After the category or folder is renamed or moved, IInfoStore.commit must be called with the
changed IInfoObject passed as a parameter.
Example: Moving and renaming categories or folders
The following function changes the name of a folder or category and moves it in to a new folder or
category hierarchy respectively.
<%!
String changeNameMove(IInfoStore iStore, int ID, String
newName, int newParentID){
String query;
IInfoObjects result;
String res = "";
query = "Select SI_NAME, SI_ID From CI_INFOOBJECTS "
+ " Where SI_ID=" + ID;
try{
result = iStore.query(query);
if ( result.size() > 0 ){
Each IInfoObject in the BusinessObjects Enterprise IInfoStore , contains a collection of all
properties assigned to that object known as a "properties bag". To retrieve IInfoObject details,
request SI_NAME, SI_DESCRIPTION, SI_KEYWORD in the query string used to recuperate the IInfoObject representing a category or folder.
Example: Retrieving the properties for a category
The following method returns the properties of a category, folder, or document as an IInfoObject
:
<%!
IInfoObject getProps(IInfoStore iStore, int ID){
String query;
IInfoObjects result = null;
IInfoObject properties = null;
String res = "";
query = "SELECT SI_FILES, SI_DESCRIPTION,"
+ " SI_KEYWORD, SI_KIND";
query += " FROM CI_INFOOBJECTS WHERE SI_ID=" + ID;
try{
result = iStore.query(query);
if (result.size() > 0){
properties = (IInfoObject)result.get(0);
}
2010-11-1653
Developing web application using ReportEngine SDK
}
catch(SDKException e){
return null;
}
return properties;
}
%>
5.2.5 Working with documents
Working with documents involves opening and listing the documents, and providing facilities for saving,
sending, scheduling, and organizing documents.
5.2.5.1 Opening documents
After establishing a session for a user (see Establishing a valid SAP BusinessObjects Enterprise user's
session), you can open a document on behalf of the user.
1.
Establish a BusinessObjects Enterprise session for the user.
2.
Get an identifier for the document.
The identifier can be a storage token (see Document state: storage tokens), or more simply the
document's ID.
3.
Retrieve the ReportEngine instance to open the document of desired type.
4.
Open the document using the ReportEngine.openDocument method for Interactive Analysis
documents.
5.2.5.1.1 Taking into account user rights and profiles
The user rights are set in the BusinessObjects Enterprise Central Management Console. You must
take these rights into account in your application.
You must also take into account the settings in the user's profile. See User preferences.
5.2.5.2 Displaying document lists
To display a list of documents:
1.
Use the IInfoStore.query method to return the list of IInfoObjects representing the root
directory of the user's folders and documents.
2010-11-1654
Developing web application using ReportEngine SDK
2.
Loop through the IInfoObject list and print the values of the fields of each row.
3.
Allow navigation through the folders.
Note:
IInfoObject is the base BusinessObjects Enterprise type. An IInfoObject can be used to store
any type of object in the Central Management System.
Example: Displaying a document list
The following code fragment is a helper function called getList. An IInfoObject object is passed
as a parameter to getList function, which is used to return a list of IInfoObject objects of a
required type, in this case Folders or Interactive Analysis documents.
This function is placed either at the head of the listfolders.jsp script or in a file containing helper
functions included in listfolders.jsp .
<%!
IInfoObjects getList(IInfoStore iStore,
int searchID, String kind){
IInfoObjects list = null;
String query = "SELECT SI_ID, SI_NAME, SI_PARENTID,"
list = iStore.query(query);
}
catch (SDKException sdke){
list = null;
}
return list;
}
%>
The function getInfoList is called from listfolders.jsp. The following code fragment explains how
to return a list of Interactive Analysis documents in the document root folder.
<%
int iID= 0; //ID of the root folder
IInfoObjects webiDocs = null;
String searchID=request.getParameter("sID");
if (searchID!=null) iID=Integer.parseInt(searchID);
IInfoStore iStore =
(IInfoStore)session.getAttribute("InfoStore");
webiDocs=getList(iStore,iID,(String)CeKind.WEBI);
%>
5.2.5.3 Refreshing a document list
A document list is refreshed each time IInfoStore.query is called. The results come directly from
the BusinessObjects Enterprise Central Management System (CMS) with no intermediary cache.
2010-11-1655
Developing web application using ReportEngine SDK
5.2.5.4 Saving documents
To save a document to Central Management Server, use DocumentInstance.save and DocumentIn
stance.saveAs .
Example: Saving a document
The following example shows how to open a document to be worked on, then open and save the
original version of the document.
<%
DocumentInstance doc =
myReportEngine.openDocument(docID);
String docToken doc.getStorageToken();
//User perform actions on document doc...
//Open the first version of the document and save.
DocumentInstance docToSave =
Go to Sending documents to users, groups and categories to see how to use the saveAs method.
5.2.5.5 Scheduling documents
Scheduling refreshes a document automatically at a specified time or times. When a scheduled document
refreshes successfully, an instance is created. An instance is a version of the document containing data
available at the time it is refreshed. Instances created later contains most recent data. By scheduling
and viewing instances, a user can have the latest information available for viewing, printing, and
distributing. For example, you can schedule a document to run every night so that the data viewed in
the morning is sure to be up-to-date.
To schedule a document :
1.
Query the IInfoStore to get the IInfoObject representing the specific document.
2.
Get the document's ISchedulingInfo object.
3.
Set the type and frequency of the scheduling.
4.
Use the IInfoStore to schedule the document.
Note:
The schedule action refreshes data in a document. This means that Prompt, Context, and Drill
actions must be handled automatically at run time, using information gathered from the user when
the schedule action is created.
2010-11-1656
Developing web application using ReportEngine SDK
Example: Scheduling a document
The following function shows how to schedule a document to run once immediately, or recurrently
after specific interval of days. The document instance created is stored in the list of document instances
attached to a document.
<%!
boolean scheduleDocument(IInfoStore iStore, int documentID, int days){
The report part can be a block, section, image or cell within a report. Each report part is identified by
the reference. You can find the report part reference of the particular report element by getting the
report output in XML view.
The report part feature allows you to select:
•A specific part of a report
•Multiple parts of the same report
•Report parts located in different reports, but in the same document
2010-11-1657
Developing web application using ReportEngine SDK
You cannot select different parts of a report, if the reports are located in different documents.
Note:
This feature is not supported in the Desktop Intelligence documents.
Each report part is associated with an Unique Reference and a Temporary Reference. A brief explanation
of references is given below:
•Unique Reference: It is a constant reference that identifies a single element in the report structure.
Its occurrence in the report output is associated with the data in the cube.
•Temporary Reference: It is a temporary reference that identifies a singe element in the report
structure. Its occurrence in the report output is index-based.
For example, consider a report with sections containing "Year" object.
When you request for report part using "t2" temporary reference, you will now get "2003" section.
However, if you use "u3" unique reference in both cases, you will get "2003" section.
Example: Accessing the report part using the ReportPartReference in Java
DocumentInstance wiDoc = repEng.openDocument(Integer.parseInt(strDocId));
String[] reference = new String[1];
//Find the report part reference by getting XMLView of the document.In the XMLView, you will find only
temporary reference(for example,<bag layout="bag" index = "Caroline" ref =
"2.3----y.1">)
reference[0] = "2.3----y.1";
ReportParts objReportParts = wiDoc.getReportParts(reference,OutputFormatType.PDF);
ReportPart objReportPart = objReportParts.getItem(0);
//To find unique reference, you should get the ReportPart using temporary reference and find out
" FROM CI_SYSTEMOBJECTS" +
" WHERE SI_KIND='" + CeKind.USERGROUP + "'" ;
try{
groups = iStore.query(query);
} catch (SDKException sdke){
groups = null;
}
return groups;
2010-11-1659
Developing web application using ReportEngine SDK
}
%>
BusinessObjects Enterprise uses object security, which means that security is set for each object in
the system and not for each user. Thus, for a particular object, certain users and certain groups have
the rights to different actions, depending on the object's settings. Access to folders and categories
can be restricted to specific groups and individual users. Saving a document to a specific folder and
category is a way of publishing the document to a group of users.
The system administrator uses BusinessObjects Enterprise Central Management Console to control
these permissions.
5.2.5.7.1 Sending a document to folders and categories
BusinessObjects Enterprise documents are organized in folders and/or categories.
To send a document to folders, use DocumentInstance.saveAs method. To send a document to
folders, you need to gather appropriate information from the current user before sending. To do this,
you need two web pages.
In the first page:
1.
Display the name of the document to be sent.
2.
Retrieve the IDs of:
•corporate folders and categories
•the root directory of the current user's personal categories
3.
Get and display the list of folders and categories to which the current user can send documents.
4.
Pass this information to the second page.
In the second page:
1.
Get the details entered by the user.
2.
Call DocumentInstance.saveAs .
Example: Sending a document to folders and categories
The following code fragment is used to save a document in specific folders and categories. saveDo
cAs.jsp is called by a page that passes the name and ID of the document in the query string. In
saveDocAs.jsp , the user selects the folders and categories in which the document must be saved in.
In the form, when the user clicks Save Document, saveDocAs.jsp is executed and the document is
sent according to the user's selections.
Note:
The functions getCatOrFoldersRadioButtons and webiPrefsToMap are declared here traversing
the category tree recursively.
<%!
//Return the ID of a specific folder
public int getFolderParentId(IInfoStore iStore, int userID,
String kind){
2010-11-1660
Developing web application using ReportEngine SDK
int FolderID = 0;
IInfoObjects folders = null;
String query = "SELECT SI_PARENTID FROM "
The following code fragment shows how to use the functions declared above, to create a form used to
select the folders and categories in which a document will be saved.
Example: Using the functions to create a form used to select the folders and categories
In saveDoc.jsp
<%
//get the parameters from the request object
String docId = request.getParameter("docID");
String docName = request.getParameter("docName");
String docParentFolderID = request.getParameter("corpFolder");
String corpCategID = request.getParameter("corpCategory");
String persoCatedID = request.getParameter("persoCategory");
List ccIDlist = new ArrayList();
List pcIDlist = new ArrayList();
//Validate the parameters
if (corpCategID != null)
ccIDlist.add(Integer.decode(corpCategID));
if (persoCatedID != null)
pcIDlist.add(Integer.decode(persoCatedID));
if (docId != null && docParentFolderID != null){
//Open and save the document
corpCategories and persoCategories are strings containing the ID's of the corporate and the
personal categories chosen by the active user to store the document.
5.2.5.7.2 Sending a document to the inbox of users and groups
If the current user has appropriate permissions, you can schedule to send a document to the inboxes
of users or groups of users to which the current user belongs.
To send a document, gather the appropriate information from the current user. Following is the procedure
to gather the required information and sending a document:
1.
Query the IInfoStoreInfoStore to get the IInfoObject representing the document to be
sent.
2.
Get the document's ISchedulingInfo object.
2010-11-1661
Developing web application using ReportEngine SDK
3.
Retrieve the Inbox plugin used to send a document to users.
4.
Set the destination and send options for the Inbox plugin.
5.
Create a Set containing the IDs of users or groups to which the current user can send the document.
6.
Allow the user to choose the users/groups to send the document to.
7.
Add the set of IDs created in the previous step to the Inbox plugin options.
8.
Set the type and the frequency of the scheduling.
9.
Schedule the document.
Note:
In the InfoView user interface, "Send to BusinessObjects Inbox" action is called.
You get the list of groups to which the current user can publish documents by querying the IInfoStore
. The returned IInfoObjects object contains the IDs of all groups the current user has the right to
send.
Example: Sending a document to the inbox of groups of users
<%!
//This function retrieves the Inbox destination plugin
IDestinationPlugin getInboxDestPlugin(IInfoStore iStore){
int PLUGIN_ROOT = 29;
IDestinationPlugin inboxPlugin = null;
String[] pluginsToLoad = new String[] {CeKind.DISKUNMANAGED, CeKind.SMTP, CeKind.FTP,
Kind.MANAGED_DEST};
String pluginString = "";
for (int i = pluginsToLoad.length - 1; i >= 0; i--){
pluginString += "'" + pluginsToLoad[i] + "'";
if (i != 0) pluginString += ", ";
}
String pluginQuery = "SELECT * FROM CI_SYSTEMOBJECTS"
+ " WHERE SI_PARENTID=" + PLUGIN_ROOT
+ " AND SI_NAME in "
+ "(" + pluginString + ")";
try{
IInfoObjects destPlugins = iStore.query(pluginQuery);
for (int i = 0; i < destPlugins.size(); i++){
IInfoObject plugin =
(IInfoObject)destPlugins.get(i);
if (
CeKind.MANAGED_DEST.equals(plugin.getTitle()) )
inboxPlugin = (IDestinationPlugin)(plugin);
}
} catch (SDKException e){
inboxPlugin = null;
}
return inboxPlugin;
}
//This function retrieves the IDs of the groups the current
//user can schedule to
Set getUserGroupIDs(IInfoStore iStore){
IInfoObjects groups = null;
Set IDs = new Set();
String query = "SELECT SI_ID, SI_KIND, SI_NAME"
+ " FROM CI_SYSTEMOBJECTS"
+ " WHERE SI_Kind='" + CeKind.USERGROUP + "'";
try{
groups = iStore.query(query);
int size = groups.size();
for (int i = 0; i < size; i++) {
IInfoObject obj = (IInfoObject)groups.get(i);
if (CeKind.USERGROUP.equals(obj.getKind())) {
IDs.add(new Integer(obj.getID()));
2010-11-1662
Developing web application using ReportEngine SDK
}
}
} catch (SDKException sdke){
IDs = null;
}
return IDs;
}
%>
The following code fragment shows how to send a copy of a document to the inbox of all users in the
groups. The current user is allowed to post the documents only once in a week.
Example: Sending a copy of a document to the inbox of all users in the group
Some important characteristics of Interactive Analysis documents are stored as part of the document.
You can access these properties using the DocumentInstance object.
2010-11-1663
Developing web application using ReportEngine SDK
For ReportEngine SDK, following is the process for accessing the properties of a Interactive Analysis
document:
1.
Get the collection of properties.
2.
Set/Read the property.
3.
Commit the change, if any, to the collection of properties.
5.2.6.1 Working with properties
Using ReportEngine SDK, you can access the properties of the document using DocumentIn
stance.getProperties and DocumentInstance.setProperties methods. These methods
make use of the java.util.Properties class.
There are predefined properties defined in PropertiesType. You can also add you own properties
to the document.
To avoid confusion in the Central Management System, PropertiesType.NAME is read only.
Example: Getting the name of a document
The following code fragment illustrates how to get the NAME property of a Interactive Analysis
document.
If you create a new Properties collection and add properties to that collection, when you call Doc
umentInstance.setProperties the values in the new object are added to the standard property
2010-11-1664
Developing web application using ReportEngine SDK
collection. Permanent properties such as NAME and AUTHOR are not erased in the merge. Values
for the properties that you have set in the new collection take precedence over those in the one
attached to the DocumentInstance.
5.3 Viewing reports
5.3.1 Overview
Interactive Analysis ReportEngine SDK contains classes and methods for viewing documents.
Applications for viewing Interactive Analysis documents handle prompts, and provide report and section
navigation using the ReportMap .
This chapter discusses how to use ReportEngine SDK to view Interactive Analysis reports.
5.3.2 Viewing reports
You can view complete documents, including all reports or individual reports or report pages in a variety
of different formats. The following tables show the different formats available:
Interactive Analysis Documents
BINARY
CONTENT
EXCEL
DataCentric
MHTMLHTMLDHTMLXMLCSVPDFEXCEL
YYYYDocument
YYYYYYYReport
YYYYYYYReportPage
YYDataProviders
2010-11-1665
Developing web application using ReportEngine SDK
BINARY
CONTENT
EXCEL
DataCentric
MHTMLHTMLDHTMLXMLCSVPDFEXCEL
YYDataProvder
YYYYYYReportPart
QuickReport
Page
YYYYYYY
To view an entire document, call DocumentInstance.getView .
To view an individual report, call Report.getView .
If you want to view all the reports in a document in DHTML format, you need to get views of each report
in DHTML and display them separately. See Viewing an individual report in DHTML. For more information
on supported views refer API documentation of the SupportedViews interface.
Note:
Calling DocumentInstance.getView and Report.getView generates a new storage token. For
more information on storage tokens see Document state: storage tokens.
5.3.2.1 Viewing all the reports in a document
To view all the reports in a document:
1.
Open the document.
2.
Get a binary view of the document.
You can get a binary view of a document in PDF or Microsoft Excel format. When ReportEngine
SDK converts the document into PDF, it places the reports on separate pages and creates a bookmark
for each report. In Microsoft Excel format, the reports of a Interactive Analysis document appear on
separate sheets.
3.
The binary view of the document can be obtained through an implicit response object.
You must prepare the response object to receive an appropriate content type. For Adobe Acrobat
format, set the content type to "application/pdf". For Microsoft Excel format, set the content type to
"application/vnd.ms-excel".
2010-11-1666
Developing web application using ReportEngine SDK
Example: Viewing all the reports in a Interactive Analysis document
The following code fragment displays all the reports of a document in Adobe Acrobat format. In this
example, the name of the document is stored in docName and the ID is stored in docID. Typically
these parameters are passed to the script in the query string.
<%
// get the document
String strDocID = request.getParameter("DocID");
int intDocID = Integer.parseInt(strDocID)
String strQuery = "Select SI_KIND from CI_INFOOBJECTS "
// Instantiate appropriate ReportEngine according to
// document type
ReportEngine repEng = null;
if (strKind.equals("Webi"))
repEng = reportEngines.getService(
ReportEngineType.WI_REPORT_ENGINE);
else
repEng = reportEngines.getService(
ReportEngineType.FC_REPORT_ENGINE);
// Open the document using its repository ID
DocumentInstance doc = repEng.openDocument(intDocID);
BinaryView docBinaryView = (BinaryView)doc.getView(OutputFormatType.PDF);
//Parameterize the response
response.setContentType("application/pdf");
response.setHeader("Content-Type", "application/pdf");
response.setDateHeader("expires", 0);
//output the binary stream via the response object
docBinaryView.getContent(response.getOutputStream());
%>
Note:
This example starts Adobe Acrobat Reader and displays the document using this application. Depending
on the user's browser configuration, the document will appear either in the browser or in a separate
application window.
5.3.2.2 Navigating the report
The PaginationMode object helps you to navigate through the displayed report.
The following are the supported pagination modes:
1.
Page mode: In Page mode, a report is displayed in different pages as per the format settings. You
can use all the methods in PageNavigation interface to navigate to different pages of the report.
2.
Listing mode: In Listing mode, the entire report is displayed in a single page.
Note:
Listing mode can bring in performance overhead on the large report data.
3.
QuickDisplay mode: In QuickDisplay mode, you can control the amount of data displayed in
the report. You can use PageInfo.setHorizontalRecords(int) and PageInfo.setVerticalRecords(int) to adjust the number of rows or columns of a report displayed in a page. You
2010-11-1667
Developing web application using ReportEngine SDK
can also use all the methods in PageNavigation interface to navigate to different pages of a report.
The minimum value for setHorizontalRecords(int) is 100 and for setVerticalRecords(int) is 20. The maximum number of records, height and width of page can be managed
through Central Management Console Interactive Analysis Properties.
When you save a document, the current PaginationMode is saved along with each report of the
document. When the user reopens the document, the pagination mode information with which it was
saved, is automatically considered. For performance reason, when viewing a document, the Listing
mode is changed to QuickDisplay mode by default.
To navigate to the last page of the report in QuickDisplay mode:
1.
Get the document instance.
2.
Choose a report.
3.
Set the pagination mode to QuickDisplay.
4.
Navigate the report to the last page using PageNavigation.last() .
5.
Display the report.
The following code explains how to navigate to the last page of the report using ReportEngine SDK
API.
Example: Navigating to last page of a report using QuickDisplay mode
Example: Viewing a report in a Interactive Analysis document
The following code fragment displays a selected report of a Interactive Analysis document in DHTML
format.
<%
// Get query string parameters and initialize variables
String sToken = request.getParameter("token");
String sRepID = request.getParameter("reportID");
DocumentInstance doc = null;
Report rep = null; //the report to be viewed
int iRepID = 0; //index of the selected report
// Get the document
doc = reportEngine.getDocumentFromStorageToken(sToken);
// Set the report
if ((sRepID != null)&&(!(sRepID.equals(""))))
iRepID = Integer.parseInt(sRepID);
else iRepID = 0;//set to the first report in the document
rep = doc.getReports().getItem(iRepID);
//get a view of the report in DHTML format
HTMLView docHtmlView = null;
docHtmlView = (HTMLView)rep.getView(OutputFormatType.DHTML);
// Set user agent (IE, Netscape…)
String strUserAgent = request.getHeader("User-Agent");
docHtmlView.setUserAgent(strUserAgent);
// Full Report HTML to the output stream
docHtmlView.getContent(out, "", "");
%>
<%=docHTMLView%>
5.3.2.4 Viewing an individual report in another format
You can view reports in Adobe Acrobat or Microsoft Excel format. The procedure is same as DHTML
format except that, for viewing all the reports in a document, you must get the content of the report as
a binary stream which you can output through the response object.
To view a report in a non-DHTML format:
1.
Get the binary view of the report.
2.
The binary view of the document can be obtained through an implicit response object.
Example: Viewing a report in Microsoft Excel format
The following code fragment displays all the reports in a Interactive Analysis document in Microsoft
Excel format.
//get the report to view (Report rep)
...
//get the report contents as a binary stream in Excel format
BinaryView docBinaryView =
(BinaryView)rep.getView(OutputFormatType.XLS);
//output the binary stream via the response object
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Type",
"application/vnd.ms-excel");
response.setDateHeader("expires", 0);
//output the binary stream via the response object
2010-11-1669
Developing web application using ReportEngine SDK
byte[] abyBinaryContent = docBinaryView.getContent();
//output the binary stream via the response object
outputStream.write(abyBinaryContent);
5.3.2.5 Track Data Changes
The following sections briefly describe the Track Data Changes feature and the workflow you need to
perform to activate and deactivate Track Data Changes feature.
The Track Data Changes feature
The Track Data Changes feature allows you to visualize the differences between two states of the data:
a reference state and the last refresh. It saves your time in the data analysis and reduces the time
exploring the irrelevant data. This feature compares the current data with the data that is set as a
reference and highlights any data that is added, removed, updated, increased, or decreased.
Verifying if the ReportEngine instance supports the feature
To verify the supportability of the Track Data Changes feature with the ReportEngine instance, use
ReportEngine.getCanTrackData() .
Activating and disabling the Track Data Changes feature
Before showing the data changes, the system has to track the data changes along refreshes. Since
tracking of the data changes consumes significant amount of memory and process time, it has to be
explicitly activated in the document to maintain the performance.
Use TrackData.setTrackDataMode(ReferenceUpdateMode.USER_DEFINED | Reference
UpdateMode.AUTO) to activate the Track Data Changes and TrackData.setTrackDataMode(Ref
erenceUpdateMode.DISABLED) to disable the Track Data Changes feature in the document .
Setting the data to use as a reference
When you activate the Track Data Changes, you need to set the data as a reference for comparison.
You can use the following modes to set the data reference:
•ReferenceUpdateMode.AUTO : automatically sets the current data as a reference when you
refresh a document.
•ReferenceUpdateMode.USER_DEFINED : allows you to explicitly set the data as a reference
using TrackData.setCurrentAsReference() . This way, you replace the previous data reference
with the current data. The future refreshes will be compared with the current data.
•ReferenceUpdateMode.DISABLED : allows you to disable the Track Data Changes feature.
Example: Activating the Track Data Changes
if(repEng.getCanTrackData())
{
TrackData data =wiDoc.getTrackData();
// activate trackdata
After you activate the Track Data Changes, you must set the display options for Track Data Changes.
The following table summarizes the type and condition of the tracked data changes according to object
qualification:
MeasureDetailsDimensionData changes event
TrackedTrackedTrackedAdded data
TrackedTrackedTrackedRemoved data
N/ATrackedN/AChanged data
TrackedN/AN/AIncreased data
TrackedN/AN/ADecreased data
The changed data are displayed with a predefined style based on a combination of the following cell
settings:
•Font Style
•Text Underlined
•Text Strikethrough
•Text Color
•Cell Background
The default values for these parameters are defined at server side and managed through the Central
Management Console Interactive Analysis Properties. These changes will take effect only after restarting
the Interactive Analysis server.
Note:
You can edit the font style but not the font name.
Prompts are the way to get supplementary information into a query before executing it. In ReportEngine
SDK, the way you handle prompts depends on the type of document you are working on. This section
discusses how to handle prompts in Interactive Analysis documents.
TrackDataIn
fo.showChanges(true)
TrackDa
ta.showChanges(true)
TrackDataIn
fo.showChanges(false)
TrackDa
ta.showChanges(false)
Prompts are raised when a document is refreshed using DocumentInstance.refresh . The refresh
operation executes the query and therefore needs to collect the supplementary information that resolves
filters and contexts.
Note:
Prompts that resolve universe contexts must be filled before the standard prompts. See Handling context
prompts.
2010-11-1672
Developing web application using ReportEngine SDK
5.3.3.1 Documents with a single simple prompt
One of the simplest and most common prompt is one that resolves a query filter. For example, "Enter
the year: " to which a user responds "2003" and the data retrieved by the query is restricted to the year
2003.
Example: Handling a single, simple prompt
The following code fragment illustrates how to handle a single, simple prompt. ("Simple prompt" means
standard, text-entry prompts only)
The code in this example is from a JSP called refresh.jsp. When the user chooses to refresh a
document, refresh.jsp is executed, then, when the prompt is filled, view.jsp is executed.
DocumentInstance doc = reportEngines.getServiceFromStorageToken(Token);
if (doRefresh) doc.refresh(); //refresh first time only
Prompts prompts = doc.getPrompts();
//try to enter values and set prompts
String[] values = request.getParameterValues("PromptInput");
if ((values != null)&&(!(values[0].equals(""))))
{
prompts.getItem(0).enterValues(values);
doc.setPrompts(); //also sets getMustFillPrompts to false
}
/get user input
if (doc.getMustFillPrompts()) {
This example does not show how to set the Boolean variable doRefresh. One way to set this variable
is to include an extra parameter in the query string for refresh.jsp. When DoRefresh is "F", doRefresh
is false.
The workflow for refresh.jsp for a document with simple prompt is:
1.
Get the DocumentInstance object for the document.
2.
Get the Prompts collection for the document.
3.
Enter the values and set the Prompt for the document.
Note:
The first time refresh.jsp is executed, this step will not work as the user has not yet entered a
value for the Prompt .
2010-11-1673
Developing web application using ReportEngine SDK
4.
Do one of the following:
•if the Prompt is not filled, display a form to get a value from the user.
The first time the file is executed.
The form's action parameter is set to refresh.jsp so that this file is executed when the user
clicks the OK (submit) button.
•Otherwise, execute view.jsp to display the document's reports.
5.3.3.2 Using the storage token to retrieve a DocumentInstance
When handling any kind of prompt, if you use the storage token to retrieve the document, you must be
careful to use the correct token. The storage token changes after calls to DocumentInstance.refresh
and DocumentInstance.setPrompts .
For more information on storage tokens see Document state: storage tokens.
5.3.3.3 Documents with many simple prompts
To handle many simple prompt objects, you can extend the workflow of a single simple prompt (Handling
prompts) with a form into which the user can enter values for all the prompts, and a script that handles
these values.
The problem this extension raises is that, you must dynamically set the names of the inputs in the form
that carry the values of each prompt. To achieve this, you can construct a name using a string constant,
for example "PV", and the position of the prompt in the prompts collection.
Example: Dynamically creating input names
The following code fragment illustrates how to dynamically create names for the inputs of a form.
See the example "Handling many, simple prompts" for an illustration on how to retrieve the values in
these inputs from the query string.
Example: Handling many, simple prompts
The following code fragment illustrates how to handle many, simple prompts in a Interactive Analysis
document. ("Simple prompt" means standard, text-entry prompts.)
The code in this example is from a page called refresh.jsp. When the user chooses to refresh a
document, refresh.jsp is executed, then, when the prompt is filled, view.jsp is executed.
<%
//get the document and its prompts
DocumentInstance doc = reportEngine.getServiceFromStorageToken(token);
if (doRefresh) doc.refresh(); //refresh first time only
Prompts prompts = doc.getPrompts();
//try to get and enter values from the query string
// valuesSelected is true when the user completes the form
if (valuesSelected) {
for (int j = 0; j < prompts.getCount(); j++) {
//use (recreate) the parameter names created in the form
String[] values =
request.getParameterValues(("PV" + j));
if ((values != null)&&(values.length != 0))
prompts.getItem(j).enterValues(values);
}
doc.setPrompts(); //also sets getMustFillPrompts to false
}
//get user input
if (doc.getMustFillPrompts()) {
//build a form to get user input for the prompt
%>
<form
</tr>
<%
}
//and add a row to the table for the submit button
// DoRefresh and ValuesSelected help keep track of
// where we are in the workflow
%><tr><td>
}
else //all prompts are filled and can now display the report
response.sendRedirect("view.jsp?
2010-11-1675
Developing web application using ReportEngine SDK
%>
Token="+doc.getStorageToken());
Note:
A flag is now required to determine if there are prompt values in the query string. This example uses
a hidden input in the form, ValuesSelected, which is converted to a boolean when it is retrieved.
However, you can also use the first prompt parameter PV0 for this purpose.
5.3.3.4 Prompts with simple lists of values
A List Of Values (Lov ) is a set of values associated with a universe object. These values are the
corresponding values found for the object in the database. The universe designer can edit this set as
a part of creating the object in the universe. For example, the Quarter object can have the following list
of values {Q1, Q2, Q3, Q4}, and the Customer object can have a list of values like this: {Adams, Arkwright,
Baker, Bean, ..., Zane}. These values are defined when the designer creates the object, but can be
refreshed, to accommodate changes in the database, automatically or manually. For information on
refreshing lists of values, see Chunking long lists of values.
Handling prompts that contain Lov objects involves extending the workflow for many, simple prompts
(Handling prompts). To do this, check if the prompt object has an associated Lov by calling
Prompt.hasLOV . If there is a list of values for the prompt, get the values in the list with Lov.getAl
lValues , then display them in the user input form, with Lov.getValues , as options of HTML select
tag.
Note:
Prompt.getLOV automatically refreshes the report. This can cause problems with nested prompts
which must be handled seperately. See Handling nested prompts.
Example: Displaying a simple list of values
The following code fragment illustrates how to get the values of a Lov object and display them in a
form.
//get user input
if (doc.getMustFillPrompts()) {
//build a form to get user input for the prompt
%><form
name="PromptsForm"
action="refresh.jsp"
method="post">
<table><%
for (int i = 0; i < prompts.getCount(); i++) {
The example "Handling multivalued prompts" shows how to modify the select tag to handle multivalued
prompts.
5.3.3.5 Optional Prompts
When a prompt is set as optional and when you run the query, user input for that prompt is optional.
You use ConditionalPrompt.setOptional(boolean) method to set a prompt as optional. A
true value as parameter sets it as optional and a false value sets it otherwise. Use Prompt.isOp
tional() to check if the prompt is a optional prompt.
For example, if you have three prompts in a Interactive Analysis report and one of them is defined as
optional and when you run this query, you need not fill value for this optional prompt.
Note:
•Optional prompts are not applicable for nested and hierarchical prompts.
•Optional prompts are applicable to ConditionPrompt but not applicabale for RankCondition
// Add result objects to the query
q.addResultObject(country);
q.addResultObject(revenue);
ConditionContainer condCon = q.createCondition(LogicalOperator.OR);
ConditionObject condObj = condCon.createConditionObject(country);
FilterCondition filterCon = condObj.createFilterCondition(Operator.IN_LIST);
ConditionPrompt condPrompt = filterCon.createConditionPrompt("Country ?");
// Set the condition for prompt as optional
condPrompt.setOptional(true);
// Run the query and fetch the data
dp.runQuery();
doc.refresh();
out.print("Document has prompt: " +doc.getMustFillPrompts());
Prompts prompts = doc.getPrompts();
Prompt prompt = prompts.getItem(0);
out.print("Prompt is Optional: "+prompt.isOptional());
5.3.3.6 Constrained prompts
A prompt is constrained if the answer must come from the prompt's list of values (Lov ). In Interactive
Analysis, to create constrained prompts select Select Only From List when creating a prompt filter for
a query.
You can detect if a prompt is constrained with Prompt.isConstrained .
5.3.3.7 Multivalued prompts
Until now we have considered only prompts that can have one value. However, some prompts can
require several values before it is filled. For example, the prompt, "Store name In list" can have one or
many responses before it is filled, whereas the prompt, "Year Equals" can have only one response.
Note:
For prompts that use the Between operator, such as, Sales revenue is between X and Y; the user must
specify both X and Y before the prompt is considered complete. However, Interactive Analysis forms
these kinds of prompts as two separate prompts, you need not treat them as a multivalued prompt.
Use Prompt.getType() , to detect how many values the prompt requires. A prompt can either be
PromptType.Mono or PromptType.Multi.
2010-11-1678
Developing web application using ReportEngine SDK
Example: Handling multivalued prompts
The following code fragment illustrates how to modify the <select> tag of the previous example to
handle multivalued prompts.
<td><%
if (prompt.getType()==PromptType.Mono){%>
<select name=<%="PV"+i%> size=1><%
}
//multivalued LOV needs a different select statement
else {%>
<select name=<%="PV"+i%> multiple size=5><%
}
//add values in LOV to the select list
for (int k = 0; k < lovValues.getCount(); k++) { %>
<option value="<%=lovValues.getValue(k)%>">
<%=lovValues.getValue(k)%>
</option><%
}%>
</select>
</td>
5.3.3.8 Prompts with multicolumn lists of values
A universe designer can create a list of values that has many columns.
You can check a list of values with more than one column using Values.isMultiColumns .
In ReportEngine SDK, a multicolumn list of values is represented as rows in a table with the RowValue
interface. Use Values.getRowValue to get a row in the table. And then RowValue.getHeader and
RowValue.getItem displays the values in the list.
Note:
Prompt.enterValues uses only the first value in each row to identify the row. When the user selects
a row, make sure you pass just the value in the first column (index = 0) of the row to Prompt.enterValues . The example below illustrates this.
Example: Handling multicolumn lists of values
The following code fragment illustrates how to display multicolumn lists of values in the select block.
if (prompt.hasLOV()) { //display the list of values
<%
//get value and text for the option tag
for (int k = 0; k < lovValues.getCount(); k++) {
String value = lovValues.getValue(k);
String valueText = value;
if (lovValues.isMultiColumns()) {
//MULTICOLUMN VALUES (2/2) option is a row
RowValue row = lovValues.getRowValue(k);
value = row.getItem(0);
valueText = "";
for (int n = 0;n < row.getCount(); n++) {
//build a string to display the <option> tag
if (n == 0) valueText = row.getItem(n);
else valueText = valueText + " | " +
row.getItem(n);
}
}
%><option value="<%=value%>">
<%=valueText%>
</option><%
}%>
</select>
</td>
</tr>
}
Note:
In multicolumn lists of values, value and valueText are different. The variable value contains just
the first value in the row, which is passed to Prompt.enterValues to fill the prompt, whereas
valueText displays all the values in a row.
5.3.3.9 Chunking long lists of values
Some objects, for example Customer name, can have a very long list of values. The Lov interface has
methods that you can use to divide long lists of values into chunks that are easier to display, and easier
for the user to browse.
Following are the methods used for Lov batching:
•Lov.getCurrentBatchIndex
•Lov.getValues
•Lov.getCurrentBatchName
•Lov.setBatchSize
5.3.3.10 Handling nested prompts
Sometimes a list of values contains its own prompts. A prompt in a list of values is called a nested
prompt. Nested prompts can be raised when a document containing prompts is refreshed and the
prompts have lists of values that contain their own prompts.
2010-11-1680
Developing web application using ReportEngine SDK
If a list of values contains prompts, those prompts must be filled before you can fill the prompts in the
next level up.
Example: Order of filling a hierarchy of nested prompts
Consider the following set of prompts:
Select a town from the list: (prompt in country)
Select a state from the list: (prompt on list of towns)
Select a country from the list: (prompt on list of states)
Each prompt qualifies the one above it in the hierarchy; the country must be defined before a state
can be defined and, similarly, a state must be defined before a town can be defined.
Use Lov.mustFillNestedPrompts to check if a list of values contains its own prompts, then use
Prompt.enterValues and Lov.setNestedPrompts to enter values and set the nested prompts
respectively.
Example: Handling nested prompts
The following code fragment illustrates the recommended method for handling nested prompts. In this
example, prompts and nested prompts are handled by the recursive function fillPrompts.
//get the document and its prompts
DocumentInstance doc = re.getDocumentFromStorageToken(token);
if (doRefresh) doc.refresh(); //refresh first time only
Prompts prompts = doc.getPrompts();
//if there are prompts, fill them
if (doc.getMustFillPrompts()) {
}
else //all prompts are filled and can now display the report
response.sendRedirect("view.jsp?
Token="+doc.getStorageToken());
//FUNCTION - fill prompts and handle nested prompts
public void fillPrompts (Prompts pmts, Lov parentLOV) {
//pmts is the set of prompts or nested prompts to be filled
//parentLOV is a LOV for which there are unfilled nested prompts
for (int i = 0; i < pmts.getCount(); i++) {
Lov lov = pmts.getItem(i).getLOV();
if (lov.mustFillNestedPrompts()) {
Prompts nestedPrompts = lov.getNestedPrompts();
fillPrompts (nestedPrompts , lov);
}
//get user input for pmts
//enter values for pmts
}
if (parentLOV != null) parentLOV.setNestedPrompts();
}
Note:
You can use the methods described in Prompts with simple lists of values to get the user input and
enter the values for nested prompts.
5.3.3.11 Refreshing a list of values
2010-11-1681
Developing web application using ReportEngine SDK
If the document contains prompts with a list of values, then the prompts must be filled every time the
document is refreshed. You can use Lov.refresh to provide a Refresh List button so that the user
can update the list manually.
Note:
This process is independent of the document refresh mechanism.
After calling Lov.refresh , the next time you call Lov.getValues , or Lov.getAllValues , the
list of values will be refreshed.
5.3.3.12 Refreshing a list of values containing nested prompts
If you provide a manual refresh option, you can handle any nested prompts contained in the list of
values with the fillPrompts function described in Handling nested prompts example.
Example: Refreshing a list of values containing nested prompts
The following code fragment shows how to use the fillPrompts function described in the Handling
nested prompts example to handle nested prompts raised when the list of values is refreshed manually.
//get and display the LOV
//if the user clicks "Refresh List"
lov.refresh();
Prompts nestedPmts = lov.getNestedPrompts();
this.fillPrompts (nestedPmts, lov);
5.3.3.13 Handling context prompts
Universe designers define context prompts in universes to ensure that the users retrieve appropriate
data when there is more than one way to get the results of a query. For more information about defining
contexts, see
The process of filling a context prompt is similar to that of filling many, simple prompts (Documents with
many simple prompts). The contexts in a document are represented by the Contexts collection, and
you can check if a document has contexts to fill with DocumentInstance.getMustFillContexts
.
To fill a context prompt:
1.
Get contexts.
2.
Display the possible values for each context and get the user's response.
3.
Enter the values for the context provided by the user.
4.
Set the contexts.
Designer's Guide
.
2010-11-1682
Developing web application using ReportEngine SDK
5.
View the report.
Viewing reports explains how to view reports.
5.3.4 Displaying a report map
ReportMap is a representation of the reports and the report sections in a Interactive Analysis document.
There are two modes for calculating the contents of a report map: incremental and non-incremental. In
incremental mode, only the requested information is calculated, and in non-incremental mode the entire
report map is calculated in one step.
To get the report map of a document, call DocumentInstance.getReportMap .
Example: Traversing the report map of a Interactive Analysis document
The following code fragment traverses the following report structure and gets a section as DHTML.
// Get the ReportMap from the document instance
ReportMap map = doc.getReportMap();
//point to the root node of the structure
ReportMapNodes root = map.getStructure();
// Get the number of reports in the document
// There are three in this case: Report1, Report2, and Report3
int count = root.getChildCount();
// Get the first report
ReportMapNode report1 = root.getChildAt(0);
// Get the name of the report (Report1)
String reportName = report1.getName();
// Get the report path (0)
String reportPath = report1.getPath();
// Check if the report contains sections (true in this case)
boolean leaf = report1.isLeaf();
// Get the number of sections in the report
// There are two in this case: Section1, Section2
int section_count = report1.getChildCount();
// Get the first section
ReportMapNode section1 = (ReportMapNode)report1.getChildAt(0);
// Get the section name (Section1)
String sectionName = section1.getName();
// Get the section path (0/0)
String sectionPath = section1.getPath();
// Get the DHTML page associated with this section
Drilling is one of the key feature of Web Intelligence documents, that helps users to analyze the document
data.
This chapter discusses how to provide drilling facilities for Interactive Analysis documents.
5.4.2 Introduction to drilling
Drilling controls the amount of details in a report.
Universe designers create hierarchies of dimensions when they create universes, for example Country,
State, City, Zip Code, Street. When users view reports, they can adjust the amount of details in the
reports by entering into the drill mode and also drill up or down according to the dimension hierarchies
(often called drill hierarchies).
Note:
Depending on the user rights, some users do not have access to the drilling functions.
Users set the scope of analysis to control how much data the Interactive Analysis includes in the DataProvider (cube) it creates, when a query is executed.
When a user executes a query, Interactive Analysis retrieves data not only for the dimensions in the
query, but also for the dimensions that the user has included in the scope of analysis. This means that
when a user drills through a dimension hierarchy, the information for the new report is in the DataProvider , and it is not necessary to execute a new query to display the drilled report. See also
Drilling out of scope: the scope of analysis.
Note:
The user executing the query need not be the user who set the scope of analysis.
Use ReportEngine SDK to drill in Interactive Analysis reports.
2010-11-1684
Developing web application using ReportEngine SDK
5.4.2.1 The drilling process
To provide users with a drill function, implement the following process:
1.
Request for a drill operation by clicking on a drill link in a report.
The request contains information about the drill operation. For example, the name of the script that
will handle the request, from which dimension the drill starts, and to which dimension it goes.
2.
Define the drill operation by initializing the document's drilling objects with the information passed
in the drill request.
3.
The script instructs Interactive Analysis to generate the HTML for the drilled report.
Interactive Analysis uses the information in the document's drilling classes to generate the drilled
view.
4.
Display the drilled view generated by Interactive Analysis.
5.
Repeat steps 2 to 4 for each request for a drill operation.
5.4.2.2 Defining the drill operation
You can only define drill operations for drillable documents. A document is considered as drillable, if
the dimensions used to form the query are part of a dimension hierarchy.
Defining the drill operation involves:
•getting the parameters of the drill request
•defining the query string parameters
2010-11-1685
Developing web application using ReportEngine SDK
•entering and leaving drill mode
•setting the drill path
The details of how you define the drill operation depends on the type of report. For information on
defining the drill operation for Interactive Analysis reports, see Drilling in reports.
5.4.2.3 Generating the HTML and viewing a drilled report
This step involves generating the HTML for the report using the drill operation you have defined. Once
you have done this, you can view the report as HTML using the normal workflows.
5.4.2.4 Drilling out of scope: the scope of analysis
An out of scope drill is one that goes up or down to a dimension that is not in the DataProvider . To
fulfill this request the query must be reformed and rerun to retrieve the requested data.
You can handle out of scope drills manually or transparently. How you manually handle out of scope
drills depends on the type of report, however, the mechanism for transparently handling out of scope
drills does not depend on the report type.
For information on manually handling out of scope drills for Interactive Analysis reports see Drilling in
reports.
5.4.2.5 Transparent Drill Outside of Cube
The Interactive Analysis facility for automatically handling out of scope drill requests is called Transparent
Drill Outside of Cube. When this is functioning, the scope of analysis of the Query is automatically reset
to incorporate the data for the requested dimension.
Supervisors can control a user's access to this facility using Supervisor.
5.4.2.6 Drill hierarchies
2010-11-1686
Developing web application using ReportEngine SDK
Hierarchies contain dimensions and are defined by universe designers. You can see drill hierarchies
in the Report Panel.
A dimension contains a list of values. When a value is selected from the list, it acts as a dimension filter.
5.4.3 Drilling in reports
Drilling Information
You can access drilling information by examining the contents of the universe (the drill hierarchies and
dimensions), or by examining the drill bar.
Drill hierarchies defined in a universe
Use Report.getNamedInterface("DrillInfo") get a DrillInfo instance.
To get the DrillHierarchies used in the report, use DrillInfo.getDrillHierarchies . A
hierarchy is used if one of its dimensions is included in the query for the report.
To get the dimensions and details that are not included in the hierarchy but are used in the report, use
DrillInfo.getFreeDimensions .
The DrillBlock object gets the drill hierarchies and dimensions for just one block (table or graph) in
the report.
Drill bar
DrillBar exposes drill and report filters, and specific drill objects added by the user. A drill object can
be a dimension, or a detail.
Defining the drill operation
A drill operation is defined in terms of drill path. A drill path is represented in ReportEngine SDK by the
DrillPath interface, and consists of a set of parameters such as the IDs of the objects (dimensions)
"from" and "to" which the user is drilling. Defining the drill operation, therefore, involves setting the
parameters of the drill path object.
To define the drill operation:
1.
Enter drill mode.
2.
Define the query string parameters, if required.
3.
Get the parameters of the drill request.
4.
Set the drill path.
Entering and leaving drill mode
You must switch a Interactive Analysis report into a drill mode so that it can perform the drilling functions.
There are two modes: ReportMode.Viewing and ReportMode.Analysis.
2010-11-1687
Developing web application using ReportEngine SDK
Calling DrillInfo.beginDrill puts a report in ReportMode.Analysis (drill) mode. Calling
DrillInfo.endDrill stops the drill session and puts a report in ReportMode.Viewing mode.
Defining the query string parameters
In Interactive Analysis, users drill with hyperlinks and a popup menu generated by Interactive Analysis
using Javascript functions and style sheets (see Introduction to drilling).
You can redefine the query string parameters with the DrillOption interface, then use the new names
to retrieve the details of the user's drill request and set the DrillPath .
Note:
You cannot change the name and path of the image used to indicate the drill up hyperlinks. This must
always be ApplicationName/images/drillup.gif.
Example: Defining the query string parameters
The following code fragment shows how to define the query string parameters used to pass drill
information to the Javascript functions. The Javascript functions generate the hyperlinks and popup
menu, which provide the user with drilling functions.
//set up the query string parameters used for drilling
DrillOption option = info.getDrillOption();
option.setBlockHolder("Block");
option.setBlockSynchronized(true);
option.setCallBackScript("drillHandler.jsp?ReportIdx=0");
option.setCallBackFrame("_self");
option.setDrillActionHolder("Action");
option.setToHolder("To");
option.setFromHolder("From");
option.setFilterHolder("Filter");
option.setHierarchyHolder("Hierarchy");
option.setStorageTokenHolder("Token");
Notice that you can add your own query string parameters to the call back script definition. Depending
on the architecture of your application, and how you manage storage tokens (document state) you
must include the storage token in the call back script definition. If you do this, remember that drilling
methods such as beginDrill and executeDrill generate new tokens for the document.
Getting the parameters of the drill request
To get the parameters of the drill request use request.getParameter andrequest.getParame
terValues. For example:
The DrillPath defines the drill operation. To set the drill path:
1.
Get the DrillPath object.
2.
Set the drill action.
See "Setting the action: up, down, by, or slice" below.
2010-11-1688
Developing web application using ReportEngine SDK
3.
Set the block id.
4.
Set the object id of the "drill to" element.
5.
Set the object id of the "drill from" element.
6.
Set the filter.
Setting the action: up, down, by, or slice
A user's drill actions are classified by the way they move through the drill hierarchies.
Resulting report engine actionDrill action
Up
Down
The report engine replaces the current object with
its parent in the drill hierarchy.
The report engine replaces the current object with
its child in the drill hierarchy.
The report engine replaces the current object with
By
an object that is not adjacent to it in the drill hierarchy.
Slice
The report engine adds or removes the filtered
values.
You set the drill action with DrillPath.setAction . The actions are enumerated by DrillActionType.
Setting the "from" and "to" parameters
To set the from and to parameters of the drill, you must define the elements of the drill. The elements
of the drill are the dimensions involved in the drill action and are represented by the DrillElements
interface. There are DrillElements object for the "to" and the "from" dimensions. Individual "from"
and "to" elements are represented by DrillFromElement and DrillToElement respectively.
For each drill operation:
1.
Get the drill from and to elements with DrillPath.getTo and DrillPath.getFrom respectively.
2.
Add drill elements to each collection.
2010-11-1689
Developing web application using ReportEngine SDK
3.
Set the object IDs of each drill element using the values you retrieve from the query string.
4.
For each from element, set the filter, if any.
a.
The filter remains for drill-by actions between dimensions in the same hierarchy. However for
drill-up actions, the filter is removed.
b.
For example, in the Time Period hierarchy, if you drill down to Quarters from Year = 2003, all the
quarters for 2003 are displayed, then if you drill by Year, only Year= 2003 is displayed. However
if you drill up from Quarters to Year, all the values for Years are displayed.
Example: Setting the drill path
The following code fragment shows how to set the values of the drill path. The parameters of the drill
(action, from, to, block) are retrieved as described in "Getting the parameters of the drill request".
DrillPath drill = info.getDrillPath();
//set the ACTION
if (action.equals("down"))
drill.setAction(DrillActionType.DOWN);
else if (action.equals("up"))
drill.setAction(DrillActionType.UP);
else if (action.equals("slice"))
drill.setAction(DrillActionType.SLICE);
else if (action.equals("by"))
drill.setAction(DrillActionType.BY);
//set the BLOCK
drill.setBlockID(block);
//set the TO drill elements
if (to.length > 0) {
DrillElements toElements = drill.getTo();
for (int j = 0;j < to.length; j++) {
DrillToElement toElement =
(DrillToElement) toElements.add();
toElement.setObjectID(to[j]);
}
}
//set the FROM drill elements
if (from.length > 0) {
This example assumes that there is only one value in the array filter: fromElement.setFilter(fil
ter[0]). This is true for simple drilling, however, to handle more sophisticated drilling you need touse all the values in the array of filters. Also, to set the filter, you can add the condition if !ac
tion.equals("up"), since there is no filtering in a drill-up operation. If you set a filter for a drill-up
operation, the filter is ignored.
Generating the HTML and viewing a drilled report
To generate the HTML for the report, execute the drill with DrillInfo.executeDrill , then view
the generated HTML using HTMLView.getContent (see Displaying the drilled report).
In drill mode (ReportMode.Analysis) , when you call Report.getView(OutputFormatType.DHTML) Interactive Analysis generates DHTML that uses scripts and style sheets to provide the
drilling interface (see Viewing an individual report in DHTML).
2010-11-1690
Developing web application using ReportEngine SDK
Copying the Java Script files for drilling
The Java script files used to create the drilling user interface are stored in $BusinessObjects In
stallation/common/4.0/java/lib/wihtmlgen.zip/Scripts. Copy the following files from
the Scripts directory to the same directory as your jsp script that displays the DHTML view of the report.
•bomenuIE.js
•browserDetection.js
•drillcontext.js
•drillcontextDom.js
•bomenuDOM.js
•bomenuNS.js
•IVcontext.js
•/language/language/message.js
Where language is the language of the messages.
These scripts use the styles defined in bomenu.css and the .gif files in the images folder. To get these
files, copy the following files to the directory containing the copied Java script files:
5.4.3.1 Referencing the Javascript files for drilling
The DHTML view generated by Report.getView references these files and you need to include this
in your header with HTMLView.getString("head", false) .
For an example of how to do this, see Displaying the drilled report.
5.4.3.2 Displaying the drilled report
To display the drilled report, call HTMLView.getContent .
2010-11-1691
Developing web application using ReportEngine SDK
Alternatively you can call HTMLView.getString() which retrieves both the appropriate HTML header
and the drilled report, however, it means you can't add supplementary HTML to the page.
Example: Displaying the drilled report
The following code fragment illustrates how to display a report after executing the drill:
5.4.3.3 Manually handling out of scope drill requests
Once you have set the DrillTo and DrillFrom elements, you can check if a drill dimension is not
in scope with DrillDimension.isInScope .
If the defined drill operation contains out of scope dimensions with DrillInfo.willGoOutOfScope.
If the DrillDimension is outside the scope of analysis, you can manually extend the scope of analysis
with DrillInfo.extendScopeOfAnalysis . This method returns aDrillElements collection to
which you can add extra drill dimensions that the user wants to include in the analysis.
Use DrillInfo.executeDrill to commit the changes you make to the scope of analysis.
If you want to add a query filter to the extended scope of analysis, use DrillInfo.addQueryConditions . This returns a DrillElements collection to which you can add the ID of the filter dimensions
and the associated filter values. You commit this change with DrillInfo.executeDrill . Also see,
Adding query conditions using the drill bar.
5.4.3.4 Adding objects that have prompts
If you extend the scope with an object that contains a prompt in its universe definition, you must fill the
prompts it raises before you execute the drill. See Handling prompts to find out how to do this.
2010-11-1692
Developing web application using ReportEngine SDK
5.4.3.5 Filtering with a drill bar
The DrillBar object exposes the drill filters and specific objects added by the user.
By default, the drill bar is initialized with the report filter, but it can be customized by the user to add or
remove drill objects. Drill objects can be dimensions, measures or details.
In the example below, the DrillBar object contains three objects, the Country dimension filtered on
the US value, the Resort dimension filtered on the Bahamas Beach value, and the unfiltered Service
Line object.
You can access the drill bar usingDrillInfo.getDrillBar , and add and remove objects to and
from the drill bar with DrillBar.add and IDrillBar.remove respectively.
Note:
When you remove an object from the drill bar, it is automatically removed from the report filter.
5.4.3.6 Adding query conditions using the drill bar
You can use the filters in the drill bar to add query conditions when extending the scope of analysis.
For example, if the drill bar has the filter Country = US, when the scope is extended you can use this
object to form a query condition before executing the SQL. This limits the amount of information returned
into the cube to results for Country = US, and is more rapid than retrieving the results for all the
values of Country.
The filters set in the drill bar can affect other result objects. For example, if you set the filter Month =February, the results for Quarter are automatically limited to Quarter = Q1; you cannot view the
results for Month = February and Quarter = Q3.
Note:
Changing the query affects all the reports in the document. If you add a condition to the query, information
in other reports in the document might change.
For more information see Manually handling out of scope drill requests.
5.4.3.7 Taking a snapshot of a drill
2010-11-1693
Developing web application using ReportEngine SDK
You can use DrillInfo.snapshot to take a snapshot of a drilled view and continue drilling. This
method adds a report containing the current view to the document's report list and report map.
5.5 Working with Recordsets
5.5.1 Overview
The ReportEngine SDK often uses the recordset data structure for storing information such as the
results in a data provider.
This section explains how to use the recordset classes of the ReportEngine SDK.
5.5.2 Anatomy of a recordset
In ReportEngine SDK, recordsets provide a generic way of representing the data contained in a group
of objects.
Each recordset is divided into rows and columns. Each row can be considered as a record (or a set of
fields) and you can access only one record at a time.
Recordsets
In ReportEngine SDK, the Recordset interface represents recordsets.
Field names
The Recordset.getColumnName(n) gives the name of the nth field in the current record.
2010-11-1694
Developing web application using ReportEngine SDK
The names of the fields in most recordsets are fixed. You can find the names listed under the method
descriptions in the
ReportEngine SDK API Reference
The exception to this is DataProvider.getResult which returns a recordset in which the names
of the fields are the names of the results (columns) of the query.
Moving around the recordset
Recordsets can contain only one record (row) at a time. To load it, use the following move methods of
Recordset :
•first, last, next, previous, and setRow
The Recordset class has a feature for setting the direction. You can set the direction to FORWARD
(default) or REVERSE . When the direction is set to forward, calling Recordset.next moves to the
next row in the collection, and when it is set to reverse, calling Recordset.previous moves to the
previous row in the collection. Recordset.first and Recordset.last do not depend on the
direction and always move to row 0 and row (Recordset.getColumnCount - 1) respectively.
It is good practice to set the direction and call Recordset.first or Recordset.last before you
start processing a recordset so that you know which row the Recordset object contains.
You can use Recordset.first and Recordset.isFirst to control loops that move through
recordsets.
Accessing the value of a field
In ReportEngine SDK, you can access the values of a field directly.
To access the fields of a record, use Recordset.getCellObject and provide the index of the column
in which you are interested.
Example: Accessing the values in a recordset
The following code fragment prints the types of columns and the contents of the results of a query
contained in a data provider.
Recordset rs = dp.getResult(0);
// 0: assume query has one flow
rs.first();
// Print the column types. They can be Integer, String,
// or Date.
for (int i = 0; i < rs.getColumnCount(); i++) {
Class c = rs.getColumnType(i);
StringBuffer sbt = new StringBuffer();
if ( c.equals(Integer.class) )
This code fragment assumes that rs.getDirection equals FORWARD, and the data provider (dp)
is populated.
2010-11-1696
Best Practices to improve ReportEngine performance
Best Practices to improve ReportEngine performance
The following sections helps you to work with ReportEngine in a better way.
6.1 Best Practices
SAP BusinessObjects recommends the following best practices while working with ReportEngine SDK:
•The documents opened during the BusinessObjects Enterprise session are stored and available for
the user as long as the session lasts. As a consequence, opening many documents will significantly
consume heap memory of the server. To increase the performance, close the document explicitly
when it is no longer required. Use DocumentInstance.closeDocument() method to close
documents.
•It is recommended to store a ReportEngines object in the session object once it is created for
document storage tokens to be valid throughout an application. You can retrieve ReportEngines
object when required through session object.
•Store the users IEnterpriseSession object in the Application server's session object, in this
way the user session has the same time-out as the Application server's session.
•It is recommended to use getContent(java.io.OutputStream outputStream) method to
retrieve the view of the report content. This method improves the performance and scalability of the
document retrieval by enabling chunked data transfer. It also improves the memory consumption
on both the application and the BusinessObjects servers.
•It is recommended to retrieve the List Of Values(LOV) in chunks or batches when the LOV size is
large. This will significantly reduce the amount of time taken to display the LOVs. For even better
performance, you can enable the search mode and specify the search pattern which will retrieve
only required LOVs.
•It is not recommended to use ReportInfo.getNumberOfPages() method for very large reports.
As the report must be completely computed to retrieve the number of pages, it introduces performance
overhead on the server.
•It is not recommended to use PageNavigation.last() method unless it is mandatory. This
method will compute all the pages in a report and can cause performance overhead on the server.
•Each time DocumentInstance object is retrieved from the SAP BusinessObjects Interactive
Analysis server, it is serialized and its state is recreated. Calling ReportEngine.getDocumentFromStorageToken(java.lang.String) method uses many resources on the SAP
2010-11-1697
Best Practices to improve ReportEngine performance
BusinessObjects Interactive Analysis server. So, it is recommended to use this method as less as
possible for optimal performance.
6.2 Developer tips
•When working with report parts, use unique reference to retrieve the report part from the report. An
unique reference is a constant reference that identifies a single element in the report structure, and
is associated with the data in the cube.
•If a document contains many optional prompts, then calling Prompt.enterValues() method is
optional, but DocumentInstance.setPrompts() method must be called in any case.
•The ViewModeType.ReportPart does not support OutputFormatType.HTML . Hence you
cannot view a Interactive Analysis document using ViewModeType.ReportPart and OutputFormatType.HTML in combination.
•When you use ConditionPrompt.setQuestion(String) method to change the question of
the prompt, the question string is used as an unique identifier. If the same question string is used
for more then one prompt, then the user will be prompted only once.
•The Lov.setSearchMatchCase(boolean) call does not have any effect on the LOVs defined
as "Delegated Search" in the universe, as they are searched directly from the database in a
case-sensitive manner.
•If the SQLDataProvider uses database sampling mode, then using QueryContainer.create
QueryContainer(CombinedQueryOperator) or QueryContainer.createQuery() method
will cancel the database sampling mode on the data provider.
•It is recommended to validate the customized SQL using SQLDataProvider.validateSQL()
before saving the new SQL statement by calling SQLDataProvider.changeSQL(). SQLDataProvider.validateSQL() will return false, if the SQL contains any unfilled prompts.
The SELECT clause must match the objects already present in the Query. But the FROM and the
WHERE clauses are modifiable if the user has sufficient rights.
2010-11-1698
More Information
More Information
LocationInformation Resource
SAP BusinessObjects product information
SAP Help Portal
SAP Service Marketplace
http://www.sap.com
Navigate to http://help.sap.com/businessobjects and on the "SAP BusinessObjects Overview" side panel click All Products.
You can access the most up-to-date documentation covering all SAP
BusinessObjects products and their deployment at the SAP Help Portal.
You can download PDF versions or installable HTML libraries.
Certain guides are stored on the SAP Service Marketplace and are not
available from the SAP Help Portal. These guides are listed on the Help
Portal accompanied by a link to the SAP Service Marketplace. Customers
with a maintenance agreement have an authorized user ID to access
this site. To obtain an ID, contact your customer support representative.
The SAP Service Marketplace stores certain installation guides, upgrade
and migration guides, deployment guides, release notes and Supported
Platforms documents. Customers with a maintenance agreement have
an authorized user ID to access this site. Contact your customer support
representative to obtain an ID. If you are redirected to the SAP Service
Marketplace from the SAP Help Portal, use the menu in the navigation
pane on the left to locate the category containing the documentation you
want to access.
Docupedia
Developer resources
https://cw.sdn.sap.com/cw/community/docupedia
Docupedia provides additional documentation resources, a collaborative
authoring environment, and an interactive feedback channel.
These articles were formerly known as technical papers.
https://service.sap.com/notes
These notes were formerly known as Knowledge Base articles.
https://www.sdn.sap.com/irj/scn/forums
http://www.sap.com/services/education
From traditional classroom learning to targeted e-learning seminars, we
can offer a training package to suit your learning needs and preferred
learning style.
http://service.sap.com/bosap-support
The SAP Support Portal contains information about Customer Support
programs and services. It also has links to a wide range of technical information and downloads. Customers with a maintenance agreement
have an authorized user ID to access this site. To obtain an ID, contact
your customer support representative.
Consultants can accompany you from the initial analysis stage to the
delivery of your deployment project. Expertise is available in topics such
as relational and multidimensional databases, connectivity, database
design tools, and customized embedding technology.
2010-11-16100
Loading...
+ hidden pages
You need points to download manuals.
1 point = 1 manual.
You can buy points or you can get point for every manual you upload.