SAP BusinessObjects XI 4.0 Interactive Analysis with ReportEngine SDK

Customizing SAP BusinessObjects Interactive Analysis with ReportEngine SDK
SAP BusinessObjects XI 4.0
2010-11-16
Copyright
© 2010 SAP AG. All rights reserved.SAP, R/3, SAP NetWeaver, Duet, PartnerEdge, ByDesign, SAP Business ByDesign, and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP AG in Germany and other countries. Business Objects and the Business Objects logo, BusinessObjects, Crystal Reports, Crystal Decisions, Web Intelligence, Xcelsius, and other Business Objects products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of Business Objects S.A. in the United States and in other countries. Business Objects is an SAP company.All other product and service names mentioned are the trademarks of their respective companies. Data contained in this document serves informational purposes only. National product specifications may vary.These materials are subject to change without notice. These materials are provided by SAP AG and its affiliated companies ("SAP Group") for informational purposes only, without representation or warranty of any kind, and SAP Group shall not be liable for errors or omissions with respect to the materials. The only warranties for SAP Group products and services are those that are set forth in the express warranty statements accompanying such products and services, if any. Nothing herein should be construed as constituting an additional warranty.
2010-11-16

Contents

Preface....................................................................................................................................5Chapter 1
1.1
1.2
1.3
1.4
1.5
2.1
2.2
3.1
3.2
3.3
3.4
3.5
3.6
What you can learn from this guide?.........................................................................................5
Who should use this guide?.....................................................................................................5
What you should know?...........................................................................................................5
Related documents..................................................................................................................5
List of APIs not functional from the SAP BusinessObject XI 4.0 release onwards....................6
Introduction to the ReportEngine SDK....................................................................................7Chapter 2
Packages for customizing SAP BusinessObjects Enterprise.....................................................7
ReportEngine SDK in SAP BusinessObjects Enterprise environment.......................................8
Workflow of ReportEngine SDK application.........................................................................11Chapter 3
Application essentials.............................................................................................................11
Document management.........................................................................................................11
Viewing reports......................................................................................................................11
Formatting documents...........................................................................................................12
Open document workflow......................................................................................................12
Refresh document workflow...................................................................................................12
Setting up development environment...................................................................................15Chapter 4
4.1
4.2
4.2.1
4.2.2
4.3
4.3.1
4.4
4.4.1
4.4.2
4.4.3
Installing ReportEngine SDK components..............................................................................15
Setting up the Java environment............................................................................................16
Setting up the Eclipse environment........................................................................................16
Project Setup.........................................................................................................................16
Logging with ReportEngine SDK Overview.............................................................................18
Logging Systems...................................................................................................................19
Configuring ReportEngine using webi.properties....................................................................24
What is webi.properties?........................................................................................................24
How to update webi.properties..............................................................................................24
Configuration Options............................................................................................................25
2010-11-163
Contents
Developing web application using ReportEngine SDK.........................................................27Chapter 5
5.1
5.1.1
5.1.2
5.1.3
5.1.4
5.1.5
5.1.6
5.1.7
5.2
5.2.1
5.2.2
5.2.3
5.2.4
5.2.5
5.2.6
5.3
5.3.1
5.3.2
5.3.3
5.3.4
5.4
5.4.1
5.4.2
5.4.3
5.5
5.5.1
5.5.2
Application Essentials.............................................................................................................27
Overview................................................................................................................................27
"Hello World"..........................................................................................................................27
SAP BusinessObjects Enterprise sessions............................................................................29
Implementing "Hello World"....................................................................................................32
User preferences...................................................................................................................35
Exceptions generated by the SAP BusinessObjects Enterprise SDK......................................40
Working with the ReportEngine SDK......................................................................................41
Document Management.........................................................................................................43
Overview................................................................................................................................43
Document types.....................................................................................................................43
Document state: storage tokens............................................................................................44
Organizing documents in categories and folders....................................................................47
Working with documents........................................................................................................54
Document properties.............................................................................................................63
Viewing reports......................................................................................................................65
Overview................................................................................................................................65
Viewing reports......................................................................................................................65
Handling prompts...................................................................................................................72
Displaying a report map..........................................................................................................83
Drilling in Interactive Analysis Reports....................................................................................84
Overview................................................................................................................................84
Introduction to drilling.............................................................................................................84
Drilling in reports....................................................................................................................87
Working with Recordsets.......................................................................................................94
Overview................................................................................................................................94
Anatomy of a recordset..........................................................................................................94
Best Practices to improve ReportEngine performance.........................................................97Chapter 6
6.1
6.2
Index 101
Best Practices........................................................................................................................97
Developer tips........................................................................................................................98
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
BusinessObjects Enterprise Java SDK Developer Guide
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.
13.
Click Finish.
14.
Click Finish. "Open Associative Perspective?" dialog box appears.
15.
Click Yes, to change the perspective to J2EE.
A dynamic web project is created.
4.2.2.2 Adding Rebean jars to the project
1.
In the Package Explorer, right-click on the project, select Build Path and click Configure Build Path.
2010-11-1617
Setting up development environment
"Properties for Project" window appears.
2.
Select Java Build Path and click on Libraries tab.
3.
Click on Add External JARS. "Jar Selection" window appears.
4.
Navigate to <BOBJ_INST_DIR>\Tomcat55\webapps\AnalyticalReporting\WEB-INF\lib directory, select all the jars and click Open.
The Rebean jars gets added in the library.
5.
Click OK.
6.
In the project, under WebContent directory, expand the WEB-INF directory. Right-click on lib directory and click on Import.
"Import" window appears.
7.
Expand General, select File System and click Next.
8.
Click Browse, navigate to <BusinessObjectsHome>\Tomcat55\webapps\AnalyticalRe porting\WEB-INF\lib directory, select all the jars and click Finish.
The jars gets imported to WEB-INF\lib directory.
4.2.2.3 Creating and running a JSP page
1.
In the Project Explorer, right-click on the WebContent directory, select New and then click JSP. "New JavaServer Page" window appears.
2.
Enter the "File name" and click Finish. JSP file gets created under WebContent directory.
3.
Double-click on the JSP file and write the code in it.
4.
In the Project Explorer, right-click on the JSP file, select Run Apps and click Run On Server. "Run On Server" window appears.
5.
Move the project to the right to configure it on the server and click Finish. The JSP file will be executed and the result will be shown in a browser.
4.3 Logging with ReportEngine SDK Overview
There are number of ways to trace the ReportEngine SDK application including the Java package optimized for ReportEngine SDK.
This section describes how to use the various logging systems.
2010-11-1618
Setting up development environment
4.3.1 Logging Systems
The ReportEngine SDK provides logging systems.
4.3.1.1 Logging in the Java
In the Java programming environment you can use the following logging systems.
Jakarta log4j
The Jakarta log4j system is part of the Jakarta project.
For more information, see http://Jakarta.apache.org/log4j.
java.util.logging
The java package java.util.logging is the logging system provided with JDK1.4.1.
For more information, see http://java.sun.com/j2se/1.4.1/docs/guide/util/logging/index.html.
log4j.logger.com.businessobjects.rebean.ReportEngines
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:
Trace=1, LEVEL
Adapter=log4j.logger.com.businessobjects.rebean.ReportEngines.system
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
<%@ taglib uri="/WEB-INF/wilog.tld" prefix="log" %> <jsp:useBean id="systems" class="java.util.Hashtable" scope="application" /> <%
if (systems.isEmpty()) {
systems.put("fake", "log4j.logger.com.businessobjects.rebean.ReportEngines.FakeLogger"); systems.put("debugdiag",
"log4j.logger.com.businessobjects.rebean.ReportEngines.StandardLogger");
systems.put("log4j", "log4j.logger.com.businessobjects.rebean.ReportEngines.Log4jLogger");
} %> <html> <head><title><BOProductName>Interactive Analysis Logging System</title></head> <body> <%
String uri = request.getRequestURI();
String sys = request.getParameter("sys");
String level = request.getParameter("level");
String prop = request.getParameter("prop");
String adapter = request.getParameter("adapter");
if (sys == null)
{
out.println("<form method=\"POST\" action=\"" + uri + "\">"); out.println("<h4>Change the
<BOProductName>Interactive Analysis Logging System</h4>");
out.println("<input name=\"sys\" value=\"log4j\"
type=\"RADIO\" CHECKED/>Enable Log4J, "); out.println(" properties <input value=\"Choose\" name=\"prop\" type=\"FILE\" size=\"25\"/> ");
out.println("<br><input name=\"sys\"
value=\"debugdiag\" type=\"RADIO\"/>Enable Debugdiag "); out.println("<br><input name=\"sys\" value=\"fake\" type=\"RADIO\"/>Disable Any ");
out.println("<br><br>Level <input name=\"level\"
value=\"debug\" type=\"RADIO\"/>DEBUG "); out.println("<input name=\"level\" value=\"info\" type=\"RADIO\" CHECKED/>INFO ");
out.println("<input name=\"level\" value=\"warn\"
type=\"RADIO\"/>WARN ");
out.println("<input name=\"level\" value=\"error\"
type=\"RADIO\"/>ERROR ");
out.println("<input name=\"level\" value=\"fatal\"
type=\"RADIO\"/>FATAL ");
out.println("<br><br><input type=\"SUBMIT\"
SELECTED value=\"GO\" /><br><br>"); } else {
%> <log:reinit adapter="<%=(String)systems.get(sys) %>" level="<%=level %>" lib="" prop="<%=prop %>"/> <%
out.println("<h5><a href=\""+ uri +"\">
Back</a></h5>");
2010-11-1621
Setting up development environment
} %> </body> </html>
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.
log4j.rootCategory=DEBUG, A1 # Console output log4j.appender.A1=org.apache.log4j.ConsoleAppender # File output #log4j.appender.A1=org.apache.log4j.FileAppender #log4j.appender.A1.File=infoview.log # Socket output #log4j.appender.A1=org.apache.log4j.net.SocketAppender #log4j.appender.A1.RemoteHost=bergame #log4j.appender.A1.Port=8887 # Format log4j.appender.A1.layout=org.apache.log4j.PatternLayout
2010-11-1623
Setting up development environment
log4j.appender.A1.layout.ConversionPattern= %-4r %-5p %c{10} (%x) - %m\n ## to filter REBean logging, uncomment #log4j.logger.com.businessobjects.rebean.wi=WARN #log4j.logger.com.businessobjects.rebean.wi.AxisType=WARN #log4j.logger.com.businessobjects.rebean.wi.BarType=WARN #log4j.logger.com.businessobjects.rebean.wi.HTMLView=WARN log4j.logger.com.businessobjects.rebean.wi.Report=WARN ## to filter REPORT ENGINE SERVLET, uncomment #log4j.logger.com.businessobjects.cdzlet=WARN ## to filter INFOVIEW JSP logging, uncomment #log4j.logger.scripts=WARN #log4j.logger.viewers=WARN
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:
<TOMCAT_HOME>\webapps\AnalyticalReporting\WEB-INF\classes\webi.properties
4.4.2 How to update webi.properties
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 <BOProduct­Name>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 transla­tion.
The size of binary or character object sent between the client browser and the <BOProduct­Name>Interactive Analysis serv­er.
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 inter­nal <BOProductName>Interac­tive Analysis calls.
org.apache.xalan.proces sor.TransformerFactoryImpl
In bytes: 60000
In kilobytes: 60k
11
750m
Commented out.
Uncomment and set to 1 to ac­tivate.
2010-11-1625
Setting up development environment
STORAGE_TO KEN_STACK_SIZE
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 persis­tence 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:
int ReportEngine.getStorageTokenStackSize()
boolean ReportEngine.IsStorageTokenValide(String storageToken)
ReportEngine.StorageTokenStackSize{get}
boolean ReportEngine.IsStorageTokenValide(String storageToken)
2010-11-1626

Developing web application using ReportEngine SDK

Developing web application using ReportEngine SDK
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.
<% page import="com.crystaldecisions.sdk.framework.*,
com.crystaldecisions.sdk.occa.infostore.*, com.crystaldecisions.sdk.occa.pluginmgr.*, com.crystaldecisions.sdk.plugin.*, com.crystaldecisions.sdk.plugin.desktop.server.*, com.crystaldecisions.sdk.occa.infostore.*, com.crystaldecisions.sdk.plugin.destination.smtp.*, com.crystaldecisions.sdk.plugin.destination.managed.*, com.crystaldecisions.sdk.exception.SDKException, com.crystaldecisions.sdk.occa.security.*, com.crystaldecisions.sdk.plugin.desktop.user.*, com.crystaldecisions.sdk.properties.*,
com.businessobjects.sdk.plugin.desktop.webintelligence.CeWebIntelligenceRightID"%>
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.
Example: Instantiating the ISessionMgr class
ISessionMgr mySessionMgr = CrystalEnterprise.getSessionMgr();
5.1.3 SAP BusinessObjects Enterprise sessions
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
<FORM name="LoginForm" action="Login.jsp" method="POST">
<TABLE> <TR>
<TD>Name:</TD>
<TD><input type = "text" name="Name"></TD> </TR> <TR>
<TD>Password:</TD>
<TD><input type="password" name="Pass"></TD> </TR> <TR>
<TD>Central Management System:</TD>
<TD><input type = "text" name="CMS"></TD> </TR> <TR>
<TD>Authentication:</TD>
<TD>
<select name='auth'> <option value='secEnterprise'>Enterprise</option> <option value='secLDAP'>LDAP</option> <option value='secWinAD'>WinAD</option> </select>
</TD> </TR> <TR>
<TD><input id=submit1 name=submit1
type=submit value="Login"></TD>
</TR></TABLE>
</FORM>
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.
ISessionMgr mySessionMgr =
CrystalEnterprise.getSessionMgr(); IEnterpriseSession enterpriseSession; try {
enterpriseSession = mySessionMgr.logon(name, password, CMS, auth); if (enterpriseSession != null){
session.setAttribute("EnterpriseSession",enterpriseSession);
IInfoStore iStore = (IInfoStore)enterpriseSession.getService("InfoStore");
session.setAttribute("InfoStore", iStore); }catch (SDKException sdkEx){
2010-11-1631
Developing web application using ReportEngine SDK
;
}
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.
Example: Example of index.jsp
<html> <body> <h1>Create a BusinessObjects Enterprise Session</h1> <form name="LoginForm" action="login.jsp" method="POST">
<table> <tr>
<td>Name: </td>
<td><input name="Name"></td> </tr> <tr>
<td>Password: </td>
<td><input type="password" name="Pass"></td> </tr> <TR>
<TD>Crystal Management System:</TD>
<TD><input name="CMS"></TD> </TR> <TR>
<TD>Authentication:</TD>
<TD>
<select name='auth'>
<option value='secEnterprise'>Enterprise</option> <option value='secLDAP'>LDAP</option>
</select>
</TD> </TR> <tr>
<td> <input id=s1 name=s1 type=submit value="Login"></td> </tr> </table>
</form> </body> </html>
2010-11-1633
Developing web application using ReportEngine SDK
5.1.4.2 login.jsp
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.
Example: Example of login.jsp
<%@ page import="com.crystaldecisions.sdk.framework.CrystalEnterprise" %> <%@ page import="com.crystaldecisions.sdk.framework.IEnterpriseSession" %> <%@ page import="com.crystaldecisions.sdk.framework.ISessionMgr" %> <%@ page import="com.crystaldecisions.sdk.exception.SDKException" %> <%
String CMS = request.getParameter("cms"); String userID = request.getParameter("user"); String password = request.getParameter("password"); String auth = request.getParameter("auth");
if ( CMS == null) CMS = ""; if ( userID == null) userID = ""; if ( password == null) password = ""; if ( auth == null) auth = "";
IEnterpriseSession enterpriseSession; try {
ISessionMgr mySessionMgr =
CrystalEnterprise.getSessionMgr();
enterpriseSession =
mySessionMgr.logon(userID, password, CMS,auth); if (enterpriseSession != null) {//Create and store useful objects for the session.
session.setAttribute("EnterpriseSession",
enterpriseSession);
IInfoStore iStore = (IInfoStore)
enterpriseSession.getService("InfoStore");
session.setAttribute("InfoStore", iStore);
response.sendRedirect("home.html"); } else response.sendRedirect("index.jsp");
} catch( SDKException mySDKExept) {
response.sendRedirect("index.jsp");
}
%>
5.1.4.3 home.html
This page dispalys the "Hello World!" message and link to logout.jspx.
<html> <body> <h1>Create an Interactive Analysis Session: Home Page</h1> <p>Hello World!</p> <a href="logout.jsp">Log out</a> </body> </html>
2010-11-1634
Developing web application using ReportEngine SDK
5.1.4.4 logout.jsp
This page is opened when the user clicks Log out in home.html.
<%@ page import="com.crystaldecisions.sdk.framework.IEnterpriseSession" %>
<%
IEnterpriseSession enterpriseSession; enterpriseSession =(IEnterpriseSession)
session.getAttribute("EnterpriseSession"); session.removeAttribute("EnterpriseSession"); if(enterpriseSession != null) {
enterpriseSession.logoff(); enterpriseSession = null;
}
%>
5.1.5 User preferences
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 for­mat.
(default)
Create documents using the Java Report Panel.
(default)
Create documents using the HTML Report Panel.
Start the drill action in a dupli­cate report.
Start the Drill action in the cur­rent 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 re­port 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){
String prefs = ""; String sQuery = "SELECT SI_ID, SI_NAME, SI_DATA FROM"
+ " CI_SYSTEMOBJECTS WHERE SI_ID = '" + uId + "'";
IInfoObjects users = null;
2010-11-1637
Developing web application using ReportEngine SDK
try{
users = iStore.query(sQuery); if (users.size() > 0){
IUser user = (IUser)users.iterator().next();
prefs = user.getProfileString("desktopsettings");
}
}catch(SDKException sEx){
return ""; } return prefs;
} //Convert a String of preferences to a Map Map webiPrefsToMap(String prefs){
StringTokenizer st = new StringTokenizer (prefs, "&"); Map webiPrefs = null; while (st.hasMoreTokens()) {
String s2 = st.nextToken(); StringTokenizer st2 = new StringTokenizer (s2, "="); if (st2.countTokens() == 2)
webiPrefs.put(st2.nextToken(), st2.nextToken()); } return webiPrefs;
} %>
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
<% int userID = myIEnterpriseSession.getUserInfo().getUserID(); PrintWriter myWriter = response.getWriter(); String prefs = getWebiPrefs(myIInfoStore, userID); Map prefsMap = webiPrefsToMap(prefs); if (prefsMap != null){
Iterator itr = prefsMap.entrySet().iterator(); while(itr.hasNext()) {
Map.Entry current = (Map.Entry)itr.next(); myWriter.print (
current.getKey() + "=" + current.getValue() + "<br>");
} } %>
5.1.5.1.2 Setting an option in a user profile
To set an option:
1.
Get user's preferences.
2.
Update the standard option in the Map continuing the user preferences.
3.
Convert the Map to a String.
4.
Update the user profile with IInfoStore.commit . The following code fragment enables user's profile to be updated to use the Java Report Panel.
Example: Setting a user's report panel preference to Java
<%! //Update the user's Interactive Analysis preferences. void setWebiPrefs(IInfoStore iStore, String prefs, int uId) {
2010-11-1638
Developing web application using ReportEngine SDK
String sQuery = "SELECT SI_ID, SI_NAME, SI_DATA FROM CI_SYSTEMOBJECTS WHERE SI_ID = '"
+ uId + "'"; IInfoObjects users = null; try{
users = iStore.query(sQuery); if (users.size() > 0){
IUser user = (IUser)users.iterator().next(); user.setProfileString("desktopsettings", prefs); iStore.commit(users);
}
}catch(SDKException sEx){
;
}
}
//Convert a preferences Map to a string String webiPrefsToSting(Map wPrefs){
StringBuffer sbWebiPrefs = new StringBuffer(); Iterator itr = wPrefs.entrySet().iterator(); while(itr.hasNext()) {
Map.Entry current = (Map.Entry)itr.next(); if(sbWebiPrefs.length() != 0)
sbWebiPrefs.append("&");
sbWebiPrefs.append(current.getKey()); sbWebiPrefs.append("=");
sbWebiPrefs.append(current.getValue()); } return sbWebiPrefs.toString();
} %>
The following code fragment shows how to use the functions declared above to update a user's Interactive Analysis preferences.
<% //Update a user's Interactive Analysis preferences int userID = myIEnterpriseSession.getUserInfo().getUserID(); String prefs = getWebiPrefs(myIInfoStore, userID); Map prefsMap = webiPrefsToMap(prefs); prefsMap.put( "webi_panel", "java"); setWebiPrefs(iStore, webiPrefsToSting(prefsMap), userID); %>
Note:
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.
<%@ page import= "com.businessobjects.rebean.wi.*"%>
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 you can 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.
ISessionMgr mySessionMgr = CrystalEnterprise.getSessionMgr(); enterpriseSession =
mySessionMgr.logon(userID, password, CMS,auth); if (enterpriseSession != null) {
ILogonTokenMgr iLManager =
enterpriseSession.getLogonTokenMgr() ;
ReportEngines repEngines = (ReportEngines)
enterpriseSession.getService("ReportEngines"); ReportEngine widocRepEngine = (ReportEngine)repEngines.getService(
ReportEngines.ReportEngineType.WI_REPORT_ENGINE);
session.setAttribute("widReportEngine", widocRepEngine); }
Use the "kind" attribute of a document IInfoObject to see if a Interactive Analysis ReportEngine needs to be opened.
Example: Instantiating a ReportEngine objects depending on file type
String strQuery = "Select SI_KIND from CI_INFOOBJECTS"
+ "where SI_ID=" + strDocId; IInfoObjects iDocObjects = iStore.Query(strQuery); IInfoObject iDocObject = null; try {
iDocObject = (InfoObject) iDocObjects[0]; } catch {
... } String strKind = iDocObject.Kind; ReportEngine reportEngine = null; if(strKind.Equals("Webi")) {
reportEngine = reportEngines.getService(
ReportEngineType.WI_ReportEngine); } else {
reportEngine = reportEngines.getService(
ReportEngineType.FC_ReportEngine); }
5.1.7.3 Closing a ReportEngines object
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.getStor ageTokenStackSize()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.
<%
IInfoStore iStore =
(IInfoStore)session.getAttribute("InfoStore"); IInfoObject infoView = null; String query = "SELECT STATIC FROM CI_APPOBJECTS,"
+ " CI_SYSTEMOBJECTS WHERE"
2010-11-1648
Developing web application using ReportEngine SDK
+ " (SI_PARENTID = 99 AND SI_KIND=\'"
+ CeKind.INFOVIEW + "\')"; try{
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;
try{
folders = iStore.query(query); if(folders.size() > 0)
FolderID=
((IInfoObject)folders.get(0)).getParentID(); }catch (SDKException sdke){
return FolderID;}
2010-11-1649
Developing web application using ReportEngine SDK
return FolderID;
} //Return a selectable list of categories or folders String getCategoryList(IInfoStore iStore,
int id, String kind ){ String results = ""; IInfoObject category; if (id == -1) id = 0; String sQuery = "SELECT SI_ID, SI_NAME, SI_PARENTID FROM"
+ " CI_INFOOBJECTS WHERE SI_PARENTID=" + id
+ " AND SI_KIND= \'"+ kind + "\'" ; try{
IInfoObjects categories = iStore.query(sQuery); if (!categories.isEmpty()){ results += "<ul>"; for(int i = 0; i < categories.size(); i++){
category = (IInfoObject)categories.get(i); String name = category.getTitle(); int catID = category.getID() ; results += "<li><input type=\"radio\" name=\""
+ kind + "\" value=\""
+ catID + "\" >" + name + "</li>\n";
results += getCategoryList(iStore,
category.getID(), kind);
} results += "</ul>"; }
}catch (SDKException sdke){
results = null; } return results;
} %>
The following code fragment shows how to use the functions declared above to print personal categories for a user.
<% IEnterpriseSession enterpriseSession =(IEnterpriseSession)
session.getAttribute("EnterpriseSession");
IInfoStore iStore=
(IInfoStore)session.getAttribute("InfoStore"); int userID = enterpriseSession.getUserInfo().getUserID(); int persoCatsfolderID = getFolderParentId(
iStore,userID,(String)CeKind.PERSONALCAT); String catButtons =
getCategoryList(
iStore, (String)CeKind.PERSONALCAT));
%>
Note:
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,
String kind){
int FolderID = 0; IInfoObjects folders = null; String query = "SELECT SI_ID" +
" FROM CI_INFOOBJECTS" + " WHERE SI_KIND='" + kind + "'" + " AND SI_OWNERID=" + userID;
try{
folders = iStore.query(query); if(folders.size() > 0)
FolderID = ((IInfoObject)folders.get(0)).getID();
}catch(SDKException sdke){
FolderID = -1; } return FolderID;
} //Retrieve the ID of a user's Inbox int getInboxFolderId(IInfoStore iStore, int userID){
return getFolderId(iStore,userID,(String)CeKind.INBOX);
} //Retrieve the ID of a user's favorites folder int getFavoritesPFolderID(IInfoStore iStore, int userID){
return
getFolderId(iStore,userID,(String)CeKind.FAVORITESF);
} %>
//The following example shows how to retrieve a list of documents in the current user's Inbox. See Displaying
a document list for the difinition of getlist.
<% IEnterpriseSession enterpriseSession; IInfoObjects docList = null; enterpriseSession = (IEnterpriseSession)
session.getAttribute("EnterpriseSession");
IInfoStore iStore = (IInfoStore)
session.getAttribute("InfoStore"); int userID = enterpriseSession.getUserInfo().getUserID(); int inboxID = getInboxFolderId(iStore, userID);
docList =
getList(iStore, inboxID, (String)CeKind.WEBI );
%>
Note:
See Displaying document lists for the definition of getList.
5.2.4.4 Creating categories and folders
To create categories and folders:
get the ID of the folder or category in which you wish to create a node
get the correct plug-in to create a node
2010-11-1651
Developing web application using ReportEngine SDK
commit the new object to the Central Management System
Example: Creating a new folder or category
The following example shows functions that use BusinessObjects Enterprise SDK to create a new folder or category.
<%! int addFolderOrCategory(IInfoStore iStore,
int parentFolderID,String name,
String description, String type){
int objectID = 0; IPluginInfo plugin; try{
IPluginMgr pluginMgr = iStore.getPluginMgr(); plugin = pluginMgr.getPluginInfo(type); IInfoObjects newInfoObjects =
iStore.newInfoObjectCollection();
newInfoObjects.add(plugin); IInfoObject infoObject = (IInfoObject)
newInfoObjects.get(0);
infoObject.setTitle (name); infoObject.setDescription (description); objectID = infoObject.getID(); infoObject.properties().setProperty(
CePropertyID.SI_PARENTID, parentFolderID);
iStore.commit (newInfoObjects);
}catch (SDKException e) {
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 ){
IInfoObject currResult; currResult = (IInfoObject)result.get(0); currResult.setTitle(newName); currResult.setParentID(newParentID); iStore.commit(result);
} } catch(SDKException e){
; } return res;
} %>
5.2.4.6 Retrieving the properties of a category
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 IIn foObject 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,"
+ " SI_KIND, SI_INSTANCE, SI_DESCRIPTION FROM"
+ " CI_INFOOBJECTS WHERE SI_PARENTID="
+ searchID + " AND SI_KIND = '" + kind + "'"; try{
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 =
theReportEngines.getDocumentFromStorageToken(docToken); docToSave.save(); %>
Note:
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){
IInfoObjects documentList; ISchedulingInfo schedulingInfo; IInfoObject document; String res = ""; boolean success = true; try {
String schedQuery = "Select SI_schedulingInfo From"
+ " CI_INFOOBJECTS Where SI_ID="
+ documentID;
documentList = iStore.query( schedQuery); if ( documentList.size() > 0 ){
document= (IInfoObject) documentList.get(0); schedulingInfo = document.getSchedulingInfo(); if (days == -1){
schedulingInfo.setType(CeScheduleType.ONCE);
schedulingInfo.setRightNow(true);
} else {
schedulingInfo.setIntervalDays(days);
schedulingInfo.setType(
CeScheduleType.DAILY );
} iStore.schedule(documentList);
}
} catch( SDKException e ) {
success = false ; } return success;
} %>
The following code fragment shows how to call the scheduleDocument function to schedule a document to be run once immediately.
<% String docId = request.getParameter("docID"); IInfoStore iStore = (IInfoStore)session.getAttribute("InfoStore"); scheduleDocument(iStore, Integer.parseInt(docId), -1); %>
5.2.5.6 Using ReportPart
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.
2001 - (temporary reference - t1, unique reference - u1)
2002 - (temporary reference - t2, unique reference - u2)
2003 - (temporary reference - t3, unique reference - u3)
When you request for report part using "t2" temporary reference, you will get "2002" section.
Again, consider that after data refresh, the "2002" section in the report gets deleted,
2001 - (temporary reference - t1, unique reference - u1)
2003 - (temporary reference - t2, unique reference - u3)
2004 - (temporary reference - t3, unique reference - u4)
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
unique reference associated to it. String uniqueRef = objReportPart.getUniqueReference(); BinaryView myBOView = (BinaryView) objReportParts.getView(); OutputStream outputStream = response.getOutputStream(); response.setContentType("application/pdf"); response.setHeader("Content-Type","application/pdf"); response.setDateHeader("expires", 0); myBOView.getContent(outputStream);
5.2.5.6.1 Selecting report part using Media
The Media are the parameters that are used to format the report output.
The following properties are supported as media:
2010-11-1658
Developing web application using ReportEngine SDK
OutputPropertiesType.XML_UNIT
OutputPropertiesType.XML_FONT_MAPPING
OutputPropertiesType.XML_DPI_FACTOR
Example: Example of selecting report using media properties in Java
Properties properties = new Properties(); properties.setProperty(OutputPropertiesType.XML_UNIT,"metric"); ReportParts objReportParts = wiDoc.getReportParts(reference,OutputFormatType.PDF,properties);
5.2.5.7 Sending documents to users, groups and categories
The list of BusinessObjects Enterprise users to whom a document can be sent depends on:
The groups to which the current user belongs
The current user's permissions
Depending on the current user's settings for these permissions
DocumentInstance.saveAs
IInfoStore.schedule
Action
Save to Groups and Categories
Send to Inbox, FTP, email, groups.
To these groups and/or users
groups and categories to which the current user has access
groups to which the current user belongs, and/or the other users in those groups
Example: Retrieving the list of groups to which a user belongs
The following function shows how to retrieve the list of groups the current user belongs to.
<%! IInfoObjects getUserGroups(IInfoStore iStore) {
IInfoObjects groups = null; String query = "SELECT SI_ID, SI_NAME" +
" 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 "
+ " CI_INFOOBJECTS WHERE SI_Kind='"
+ kind + "'" + AND SI_OWNERID=" + userID;
try{
folders = iStore.query(query);
if(folders.size() > 0)
FolderID=((IInfoObject)folders.get(0)).getParentID();
}catch (SDKException sdke){
return FolderID;}
return FolderID; } %>
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
DocumentInstance docToSave =
webiRepEngine.openDocument(Integer.parseInt(docId));
if( docToSave != null)
docToSave.saveAs( docName,
Integer.parseInt(docParentFolderID),
ccIDlist,pcIDlist); } %>
Note:
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
<%
String docId = request.getParameter("docID");
IInfoStore iStore =
(IInfoStore)session.getAttribute("InfoStore");
IDestinationPlugin inboxPlugin = null; IManagedOptions destOptions = null; ISchedulingInfo schedulingInfo = null; IInfoObjects documentList = null; IInfoObject document = null; try {
String docQuery = "Select SI_schedulingInfo FROM"
+ " CI_INFOOBJECTS Where SI_ID=" + docId; documentList = iStore.query(docQuery); if ( documentList.size() > 0 ) {
document= (IInfoObject)documentList.get(0); schedulingInfo = document.getSchedulingInfo(); inboxPlugin = getInboxDestPlugin(iStore); IDestination destination =
schedulingInfo.getDestination();
if (inboxPlugin != null){
destOptions =(IManagedOptions)
inboxPlugin.getScheduleOptions();
destOptions.setDestinationOption(
IManagedOptions.CeDestinationOption.ceInbox);
destOptions.setSendOption(
IManagedOptions.CeManagedSendOption.ceCopy);
Set IDs = getUserGroupIDs(iStore);
Set destinationIDs =
destOptions.getDestinations();
destinationIDs.clear();
destinationIDs.addAll(IDs);
destination.setFromPlugin(inboxPlugin);
schedulingInfo.setIntervalDays(7);
schedulingInfo.setType(CeScheduleType.DAILY);
iStore.schedule(documentList);
}
}
} catch( SDKException e ) {
throw e;
}
%>
5.2.6 Document properties
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.
DocumentInstance doc =
myReportEngine.openDocument(docID);
java.util.Properties props = doc.getProperties (); String dName = props.getProperty (PropertiesType.NAME);
5.2.6.2 Adding your own properties to the document
Use Properties.setProperty to add your own properties to the document.
Example: Adding RefreshCount property to a document
The following code fragment illustrates how to add the RefreshCount property to a Interactive Analysis document.
DocumentInstance doc = myReportEngine.openDocument(docID); java.util.Properties props = doc.getProperties (); props.setProperty ("RefreshCount", "12"); doc.setProperties (props);
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 DataCen­tric
MHTMLHTMLDHTMLXMLCSVPDFEXCEL
YYYYDocument
YYYYYYYReport
YYYYYYYReportPage
YYDataProviders
2010-11-1665
Developing web application using ReportEngine SDK
BINARY CONTENT
EXCEL DataCen­tric
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 "
+ "where SI_ID=" + strDocID;
IInfoObjects iDocuments = iStore.query(strQuery); IInfoObject iDocument = (IInfoObject) iDocObjects.get(0); String strKind = iDocObject.getKind();
// 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.setVerti calRecords(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 setVertical Records(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
DocumentInstance wiDoc = repEng.openDocument(docId); Reports reps = wiDoc.getReports(); Report rep = reps.getItem(0); rep.setPaginationMode(PaginationMode.QuickDisplay); PageNavigation pageNavigation = rep.getPageNavigation(); pageNavigation.last(); HTMLView htmlView = (HTMLView)rep.getView(OutputFormatType.DHTML); PrintWriter writer = response.getWriter(); htmlView.getContent(writer, "", ""); writer.close();
5.3.2.3 Viewing an individual report in DHTML
DHTML is the standard format for viewing reports.
To view an individual report in DHTML format:
1.
Get a document instance
2.
Set the report
3.
Get a view of the report in DHTML format
4.
Display the report
2010-11-1668
Developing web application using ReportEngine SDK
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
2010-11-1670
Developing web application using ReportEngine SDK
data.setTrackDataMode(ReferenceUpdateMode.USER_DEFINED); data.setCurrentAsReference(); }
Setting the display options
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.
Example: Setting the track data changes options
//get style options TrackDataOptions options = data.getTrackDataOptions();
2010-11-1671
Developing web application using ReportEngine SDK
TrackDataOption option = options.getInsertedOption(); Decoration decoration = option.getDecoration(); Attributes attributes = decoration.getAttributes(); attributes.setBackground(Color.WHITE); attributes.setForeground(Color.GREEN); //change the font style Font font = decoration.getFont(); font.setStyle(StyleType.ITALIC); data.update();
Viewing and hiding the data changes
The following table describes the methods you can use to view and hide the data changes:
To hide the data changesTo view the data changes
In the current active report
In all reports
Example: Viewing the data changes in a specific report
Reports reps = wiDoc.getReports(); Report rep = reps.getItem(0); TrackDataInfo trackDataInfo = rep.getTrackDataInfo(); trackDataInfo.showChanges(true);
5.3.3 Handling prompts
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()) {
//build a form to get user input for the prompt
%>
<formname="PromptsForm"
action="refresh.jsp?Token=<%=doc.getStorageToken()%>" method="post"> <input name="PromptInput" type="text"/>
<input name="Submit" type="submit" value="OK" /> </form> <%
} Response.sendRedirect("view.jsp?
Token="+doc.getStorageToken());
Note:
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.
<form name="PromptsForm" action="refresh.jsp" method="post">
<table><%
for (int i = 0; i < prompts.getCount(); i++) {
%><tr>
<td>Enter a value for prompt number <%=i%>:</td>
<td><input name=<%="PV"+i%> type="text"/></td> </tr><% } %><tr><td>
<input name="Submit" type="submit" value="OK" /> </tr></td>
</table>
</form>
2010-11-1674
Developing web application using ReportEngine SDK
Note:
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
name="PromptsForm"
action="refresh.jsp"
method="post"> <table>
<%
//add a row to the table for each prompt
// the names of inputs are created dynamically
for (int i = 0; i < prompts.getCount(); i++) {
%>
<tr>
<td><%=prompts.getItem(i).getName()%></td> <td><input name=<%="PV"+i%> type="text"/></td>
</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>
<input name="Token" type="hidden"
value="<%=doc.getStorageToken()%>" />
<input name="DoRefresh" type="hidden"
value="false" />
<input name="ValuesSelected" type="hidden"
value="true" />
<input name="Submit" type="submit" value="OK"> </tr></td>
</table> </form> <%
} 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++) {
Prompt prompt = prompts.getItem(i);
2010-11-1676
Developing web application using ReportEngine SDK
if (prompt.hasLOV()) {
Values lovValues = prompt.getLOV().getAllValues();
%>
<tr> <td><%=prompt.getName()%></td> <td> <select name=<%="PV"+i%> size=1> <% for (int k=0; k < lovValues.getCount(); k++){
%> <option value="<%=lovValues.getValue(k)%>"> <%=lovValues.getValue(k)%> </option><% }%> </select> </td> </tr><%
}
}
%><tr><td>
<input name="Submit" type="submit" value="OK">
</tr></td>
</table>
</form> <%}%> <%
Note:
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
Prompt.
Example: Create the document with optional prompt
String universeId =((IUniverse)ceInfoobject).buildUniverseIdString(); DocumentInstance doc = repEng.newDocument(universeId); ReportContainer report = doc.createReport("Report1"); DataProviders dps = doc.getDataProviders(); // Retrieve the 1st data provider DataProvider dp = dps.getItem(0);
2010-11-1677
Developing web application using ReportEngine SDK
// Retrieve the universe objects DataSource ds = dp.getDataSource(); DataSourceObject country = ds.getClasses().getChildByName("Country"); DataSourceObject revenue = ds.getClasses().getChildByName("Revenue"); Query q = dp.getQuery();
// 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.enter Values . 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
Values lovValues = prompt.getLOV().getAllValues(); %><tr>
<td><%=prompt.getName()%></td>
<td><%
if (lovValues.isMultiColumns()) {
//MULTICOLUMN VALUES (1/2) display the column names
String colNames = ""; for (int m = 0; m < lovValues.getRowValue(0).getCount(); m ++)
colNames = colNames + " | " + lovValues.getRowValue(0).getHeader(m);
%><%=colNames%><br><% } //assume multivalue LOV %><select name=<%="PromptValue"+i%>
multiple size=5>
2010-11-1679
Developing web application using ReportEngine SDK
<% //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()) {
this.fillPrompts (prompts, null); doc.setPrompts();
} 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
2010-11-1683
Developing web application using ReportEngine SDK
Report report = doc.setPath(sectionPath); HTMLView view = report.getView(OutputFormatType.DHTML);
5.4 Drilling in Interactive Analysis Reports
5.4.1 Overview
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 Dat aProvider (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 Dat aProvider , 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:
String token = request.getParameter("Token"); String block = request.getParameter("Block"); String action = request.getParameter("Action"); String[] to = request.getParameterValues("To"); String[] from = request.getParameterValues("From"); String[] hierarchy = request.getParameterValues("Hierarchy"); String[] filter = request.getParameterValues("Filter");
Setting the drill path
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 hier­archy.
Slice
The report engine adds or removes the filtered values.
You set the drill action with DrillPath.setAction . The actions are enumerated by DrillAction Type.
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) {
DrillElements fromElements = drill.getFrom();
for (int k = 0; k < from.length; k++) {
DrillFromElement fromElement =
(DrillFromElement) fromElements.add(); fromElement.setObjectID(from[k]); if ((filter != null) && (filter.length > 0))
fromElement.setFilter(filter[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 to use 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(OutputFormat Type.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:
$BusinessObjects Installation/common/4.0/java/lib/wihtml
gen.zip/skin_name/bomenu.css
skin_name is one of: skin_default, skin_corporate, or skin_coloredline.
The fonts used in bomenu.css do not include some special characters. To display characters such as the yen symbol (¥) use bomenu_fe.css.
$BusinessObjects Installation/common/4.0/java/lib/wihtmlgen.zip/images/
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:
<% HTMLView htmlView = null; htmlView = (HTMLView) rep.getView(OutputFormatType.DHTML); String htmlHeader = htmlView.getStringPart("head", false); %> <html>
<!-- DRAW HEADER --> <head>
<link rel="stylesheet"
type="text/css" href="style/bomenu.css"> <%=htmlHeader%>
</head>
<!-- DRAW REPORT--> <%=htmlView.getStringPart("body", true)%>
</html>
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.addQueryCondi tions . 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) )
sbt.append("Integer");
if ( c.equals(String.class) )
sbt.append("String");
if ( c.equals(Date.class) )
sbt.append("Date");
sbt.append(";"); System.out.println(sbt.toString());
}
// Print the recordset contents: column names and data while (!rs.isLast()) {
// column names StringBuffer sbn = new StringBuffer(); for (int j = 0; j < rs.getColumnCount(); j++) {
sbn.append( rs.getColumnName(j).toString() );
2010-11-1695
Developing web application using ReportEngine SDK
sbn.append(";");
} System.out.println(sbn.toString());
// data for (int k= 0; k< rs.getColumnCount(); k++) {
sbd.append( rs.getCellObject(k).toString() ); sbd.append(";");
} System.out.println(sbd.toString());
rs.next();
}
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.getDocument FromStorageToken(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 OutputFor matType.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(). SQLDat aProvider.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 infor­mation
SAP Help Portal
SAP Service Marketplace
http://www.sap.com
Navigate to http://help.sap.com/businessobjects and on the "SAP Busi­nessObjects 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.
http://service.sap.com/bosap-support > Documentation
Installation guides: https://service.sap.com/bosap-instguides
Release notes: http://service.sap.com/releasenotes
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.
https://boc.sdn.sap.com/
https://www.sdn.sap.com/irj/sdn/businessobjects-sdklibrary
2010-11-1699
More Information
LocationInformation Resource
SAP BusinessObjects articles on the SAP Community Network
Notes
Forums on the SAP Community Network
Training
Online customer support
https://www.sdn.sap.com/irj/boc/businessobjects-articles
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 in­formation 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.
Consulting
http://www.sap.com/services/bysubject/businessobjectsconsulting
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...