Tag Archives: sdk

How to create a webi document using Java Report Engine SDK

This post describes the typical workflow required to create a new Webi document in BO XI 3.1. You can download the compete code here . We will consider an example how to create a simple Webi document based on Island Resorts Marketing universe that will display resort service and revenue from that service for US.

Connect to CMS and initialize engine

The first steps are establishing connection with the CMS and initializing the report engine.

// Connect to CMS
ISessionMgr sessionMgr = CrystalEnterprise.getSessionMgr();
IEnterpriseSession enterpriseSession = sessionMgr.logon(user, pass, host, auth);
// Initialize Webi report engine
ReportEngines reportEngines = (ReportEngines) enterpriseSession.getService("ReportEngines");
ReportEngineType type = ReportEngines.ReportEngineType.WI_REPORT_ENGINE;
ReportEngine reportEngine = (ReportEngine) reportEngines.getService(type);

Create new document

First, we perform CMS query to find the universe Island Resorts Marketing (which is one of the standard sample universes). (It is assumed that the universe exists).

IInfoStore infoStore = (IInfoStore) enterpriseSession.getService("InfoStore");
String unvQuery = "select * from CI_APPOBJECTS where SI_KIND = 'Universe'" 
                + " and SI_NAME='Island Resorts Marketing'";
IInfoObjects infoObjects = (IInfoObjects) infoStore.query(unvQuery);
IInfoObject infoObject = (IInfoObject)infoObjects.get(0);

Second, we actually create a new document.

DocumentInstance documentInstance = reportEngine.newDocument("UnivCUID="+infoObject.getCUID());

After this we initialize some helper variables. Data Provider and Query describe the same (query). Query is an interface to add objects and conditions, change properties such as maximum row retrieved etc. Data Provider is an interface primarily to run, purge the query etc. Data Source is equivalent to universe. If universe has multiple queries but each query use the same universe, there will be only one data source. Data Source provides all available objects in the universe.

DataProviders dps = documentInstance.getDataProviders();
DataProvider dataProvider = dps.getItem(0);
Query query = dataProvider.getQuery();
DataSource dataSource = dataProvider.getDataSource();

Build the query

First, we add a couple of objects available in the data source – Service and Revenue.

DataSourceObjects objects = dataSource.getClasses();
query.addResultObject(objects.getChildByName("Service"));
query.addResultObject(objects.getChildByName("Revenue"));

Second, we construct the condition. The condition is County=’US’.

ConditionContainer container = query.createCondition(LogicalOperator.AND);
ConditionObject conditionObject = container.createConditionObject(objects.getChildByName("Country"));
FilterCondition filterCondition = conditionObject.createFilterCondition(Operator.EQUAL);
filterCondition.createFilterConditionConstant("US");

The last step is to run queries.

dataProvider.runQuery();

Build the layout

So now we can add report to the document structure. Report container contains report header, body and footer.

ReportStructure reportStructure = documentInstance.getStructure();
ReportContainer reportContainer = reportStructure.createReport("My Report");
ReportBody reportBody = reportContainer.createReportBody();

In this example, we create a table with the two fields.

ReportBlock reportBlock = reportBody.createBlock();
ReportDictionary reportDictionary = documentInstance.getDictionary();
BlockAxis hAxis = reportBlock.getAxis(TableAxis.HORIZONTAL);
hAxis.addExpr(reportDictionary.getChildByName("Service"));
hAxis.addExpr(reportDictionary.getChildByName("Revenue"));

When the report is created from scratch, all default values are blanks and zeros so it is important to set the necessary attributes such as color, font, width.

SimpleTable simpleTable = (SimpleTable)reportBlock.getRepresentation();
CellMatrix bodyMatrix = simpleTable.getBody();
CellMatrix headerMatrix = simpleTable.getHeader(null);
CellMatrix[] matrices = new CellMatrix[]{bodyMatrix, headerMatrix}; 
for (CellMatrix matrix : matrices) {
   for (int i=0; i<matrix.getColumnCount();++i)
   {   
      TableCell cell = matrix.getCell(0, i);
      Attributes attributes = cell.getAttributes();
      if (matrix == bodyMatrix) {
         attributes.setBackground(Color.white);
         attributes.setForeground(Color.black);
      } else {
         attributes.setBackground(new Color(81, 117,185));
         attributes.setForeground(Color.white);
      }
      SimpleBorder border = (SimpleBorder)attributes.getBorder();
      border.setSize(BorderSize.NONE);				
      cell.setAttributes(attributes);
      Font font = cell.getFont();
      font.setName("Arial");
      font.setSize(10);
      cell.setFont(font);
      Alignment alignment = cell.getAlignment();
      alignment.setHorizontal(HAlignmentType.LEFT);
      cell.setAlignment(alignment);
      cell.setWidth(50);
   }
}

The final step is to apply format. It is important. If you miss this step, the report structure will not be modified.

documentInstance.applyFormat();

Save the document

The final step is to save the document to a folder. We can use function
DocumentInstance.saveAs(title, int destinationFolderId, categories, personalCategories, overwrite)

First we need to find the destination folder id. We assume that the folder Report Samples exists.

String folderQuery = "select * from CI_INFOOBJECTS where SI_KIND = 'Folder'"
                   + " and SI_NAME='Report Samples'";
infoObjects = (IInfoObjects) infoStore.query(folderQuery);
infoObject = (IInfoObject)infoObjects.get(0); 
int folderId = infoObject.getID();

Now we can save the document with title “Test”.

documentInstance.saveAs("Test", folderId, null, null, true);
documentInstance.closeDocument();

Hope this helps.

Printing LoV names with Designer COM SDK

Tutorial “Getting started with Designer SDK”

using System;
using Designer;
namespace ConsoleApplication1
{
    class Program
    {
        delegate void CleanUpMethod();

        static void Main(string[] args)
        {
            Application application = new Application();
            application.Interactive = false;

            CleanUpMethod cleanUp = delegate { application.Quit(); };
            Console.CancelKeyPress += delegate { cleanUp(); }; // to handle Ctrl+C

            try
            {
                application.Logon("Administrator", 
                    "", "localhost", "secEnterprise");                
                Universe universe =
                    application.Universes.OpenFromEnterprise(
                        "webi universes",
                        "Island Resorts Marketing",
                        false);
                PrintClasses(universe.Classes, "");
                universe.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            finally
            {
                cleanUp();
            }
        }

        static void PrintClasses(Classes classes, String path)
        {
            foreach (Class theclass in classes)
            {
                String path2 = path + "/" + theclass.Name;
                foreach (Designer.Object theobject in theclass.Objects)
                {
                    if (theobject.HasListOfValues)
                    {
                        Console.WriteLine(path2 + ";" 
                            + theobject.Name + ";" 
                            + theobject.ListOfValues.Name);
                    }
                }
                PrintClasses(theclass.Classes, path2);
            }
        }

    }
}

Getting started with BusinessObjects Java SDK

BusinessObjects Report Engine Java SDK is primarily used for Web Intelligence customization. This post describes how to start development of a command line tool. Such tools can make life of report developers easier. They can be used for:

You will need:

  • A bit of programming experience
  • Eclipse IDE for Java Developers (http://www.eclipse.org/downloads/)
  • BusinessObjects Enterprise XI 3.1 server (to connect to)
  • BusinessObjects SDK libraries (see the list below)

New project in Eclipse

Download and extract Eclipse. Start it. Select default workspace folder (the new projects will be created in this folder). On the welcome page click “Go to Workbench”.

Create a new project:

1. File>New>Java Project

2. Specify project name (e.g. JavaTool).

3. Click Finish.

4. In the project folder on the disk (e.g. C:\Users\dbu\workspace\JavaTool\), create a folder lib and copy the jar files into it.

5. In Eclipse: Project>Properties>Java Build Path>Libraries, click “Add External JARs…”, OK.

6. Create package in the project. File>New>Package, type a name (e.g. org.bukhantsov.javatool), and click OK.

7. Create new class which will be starting point of the application. File>New>Class, type a name (e.g. Program), select option “public static void main” and click OK.

The generated class will be something like this:

package org.bukhantsov.javatool;
public class Program {
   /** 
   * @param args 
   */
   public static void main(String[] args) {
      // TODO Auto-generated method stub
   }
}

Let’s start

The first program will print all variables defined in Web Intelligence documents from a BOE server folder. Let’s consider functional blocks of the application.

Connect to CMS

The first thing you have to do is to connect to the BOE server.

ISessionMgr sessionMgr = CrystalEnterprise.getSessionMgr();
IEnterpriseSession enterpriseSession =
  sessionMgr.logon("Administrator", "", "localhost", "secEnterprise");

Replace “localhost” with the name of your BOE server.

Get Webi documents from CMS

When you connected, you can get the objects corresponding to Webi documents from CMS.

IInfoStore infoStore = (IInfoStore) enterpriseSession.getService("InfoStore");
String query = "select SI_NAME, SI_ID from CI_INFOOBJECTS "
             + "where SI_KIND = 'Webi' and SI_INSTANCE=0";
IInfoObjects infoObjects = (IInfoObjects) infoStore.query(query);

You can build and test the query in BusinessObjects Query Builder.

Get report engine proxy

To open Webi document, you need to get a proxy to Webi report engine web service.

ReportEngines reportEngines =
   (ReportEngines) enterpriseSession.getService("ReportEngines");
ReportEngine wiRepEngine =
   (ReportEngine) reportEngines.getService(
      ReportEngines.ReportEngineType.WI_REPORT_ENGINE);

Process Webi documents from a folder

In a loop you can process all Webi documents from a folder

for (Object object : infoObjects) {
   IInfoObject infoObject = (IInfoObject) object;
   String path = getInfoObjectPath(infoObject);
   if (path.startsWith("/")) {
      DocumentInstance widoc = wiRepEngine.openDocument(infoObject.getID());
      // process document
      widoc.closeDocument();
   }
}

The function getInfoObjectPath builds path to the Webi document. Parent of Webi document is folder, and parent of folder is folder. The root folder has id = 0.

public static String getInfoObjectPath(IInfoObject infoObject) throws SDKException {
   String path = "";
   while (infoObject.getParentID() != 0) {
      infoObject = infoObject.getParent();
      path = "/" + infoObject.getTitle() + path;
   }
   return path;
}

Print Webi document variables

ReportDictionary dic = widoc.getDictionary();
VariableExpression[] variables = dic.getVariables();
for (VariableExpression e : variables) {
   String name = e.getFormulaLanguageID();
   String expression = e.getFormula().getValue();
   System.out.println(" " + name + " " + expression);
}

Error handling

An important part of each program is error handling.

public static void main(String[] args) {
   IEnterpriseSession enterpriseSession = null;
   ReportEngines reportEngines = null;
   try {
      // * connect to CMS
      // * get report engine proxy
      // * get Webi documents from CMS 
      // * process the documents
   }
   catch (SDKException ex) {
      ex.printStackTrace();
   }
   finally {
      if (reportEngines != null) reportEngines.close();
      if (enterpriseSession != null) enterpriseSession.logoff();
   }
}

Put all together

The complete code can be downloaded from here (however without libs). You can import it from File menu: File > Import… > Existing Project into Workspace.

package org.bukhantsov.javatool;

import com.businessobjects.rebean.wi.DocumentInstance;
import com.businessobjects.rebean.wi.ReportDictionary;
import com.businessobjects.rebean.wi.ReportEngine;
import com.businessobjects.rebean.wi.ReportEngines;
import com.businessobjects.rebean.wi.VariableExpression;
import com.crystaldecisions.sdk.exception.SDKException;
import com.crystaldecisions.sdk.framework.CrystalEnterprise;
import com.crystaldecisions.sdk.framework.IEnterpriseSession;
import com.crystaldecisions.sdk.framework.ISessionMgr;
import com.crystaldecisions.sdk.occa.infostore.IInfoObject;
import com.crystaldecisions.sdk.occa.infostore.IInfoObjects;
import com.crystaldecisions.sdk.occa.infostore.IInfoStore;

public class Program {
   public static void main(String[] args) {
      IEnterpriseSession enterpriseSession = null;
      ReportEngines reportEngines = null;
      try {
         System.out.println("Connecting...");
         ISessionMgr sessionMgr = CrystalEnterprise.getSessionMgr();
         enterpriseSession = sessionMgr.logon("Administrator",
               "", "localhost", "secEnterprise");
         reportEngines = (ReportEngines) enterpriseSession
               .getService("ReportEngines");
         ReportEngine wiRepEngine = (ReportEngine) reportEngines
               .getService(ReportEngines.ReportEngineType.WI_REPORT_ENGINE);         

         IInfoStore infoStore =
               (IInfoStore) enterpriseSession.getService("InfoStore");
         String query = "select SI_NAME, SI_ID from CI_INFOOBJECTS "
                      + "where SI_KIND = 'Webi' and SI_INSTANCE=0";
         IInfoObjects infoObjects = (IInfoObjects) infoStore.query(query);
         for (Object object : infoObjects) {
            IInfoObject infoObject = (IInfoObject) object;
            String path = getInfoObjectPath(infoObject);
            if (path.startsWith("/")) {
               DocumentInstance widoc = wiRepEngine.openDocument(infoObject.getID());
               String doc = infoObject.getTitle();
               System.out.println(path + "/" + doc);               
               printDocumentVariables(widoc);
               widoc.closeDocument();
            }
         }
      }
      catch (SDKException ex) {
         ex.printStackTrace();
      }
      finally {
         if (reportEngines != null)
            reportEngines.close();
         if (enterpriseSession != null)
            enterpriseSession.logoff();
      }
      System.out.println("Finished!");
   }

   public static void printDocumentVariables(DocumentInstance widoc ) {
      ReportDictionary dic = widoc.getDictionary();
      VariableExpression[] variables = dic.getVariables();
      for (VariableExpression e : variables) {
         String name = e.getFormulaLanguageID();
         String expression = e.getFormula().getValue();
         System.out.println(" " + name + " " + expression);
      }
   }        

   public static String getInfoObjectPath(IInfoObject infoObject) 
                                        throws SDKException {
      String path = "";
      while (infoObject.getParentID() != 0) {
         infoObject = infoObject.getParent();
         path = "/" + infoObject.getTitle() + path;
      }
      return path;
   }
}

Compile and run

You can run the program Run>Run.

Getting started with BusinessObjects RE Java SDK

To build executable JAR: go File>Export, select Java>Runnable JAR file. Select launch configuration (you will probably have the only one), select destination, select “Package required libraries into generated JAR”, and click Finish.

You can run the program using the following command:

java -jar javatool.jar

Final notes

Before running your tool on a bunch of reports it should be carefully tested. Especially if you do modifications.

The purpose of the code was to demonstrate how to access report engine. It does not demonstrate the best programming practices.

Java SDK Libraries

The Java SDK libraries can be found in the installation folder with BusinessObjects client tools or on the server.

C:\Program Files (x86)\Business Objects\common\4.0\java\lib

Required libraries:

  boconfig.jar
  cecore.jar
  celib.jar
  cesdk.jar
  cesession.jar
  corbaidl.jar
  ebus405.jar
  jtools.jar
  logging.jar
  rebean.common.jar
  rebean.jar
  rebean.wi.jar
  wilog.jar
  xpp3.jar
  xpp3_min.jar
  SL_plugins.jar

Links

Webi Report Engine Documentation

Getting Started with Designer SDK in C#

You will need:

  • BusinessObjects Enterprise XI 3.x: You need BusinessObjects client tools installed on your PC, and a connection to a BusinessObjects server.
  • Visual Studio C#: You can install Microsoft Visual Studio Express from http://www.microsoft.com/express/downloads/.
  • Create new project: File > New Project… > Console Application
  • Add reference to the SDK: Project > Add Reference… > COM > BusinessObjects Designer 12.0 Object Library
  • Now you can start coding!

Getting started

The Designer SDK is quite simple and easy to use. Universe Designer API Reference is all you need to solve almost any task (that can be solved via the SDK).

Class Application is the main class that represents the Designer product. When an instance of Application is created, Desiner is started on background, and you can see designer.exe in Task Manager. The first thing you usually do starting Designer is logging in. The same should be done in the program using either function LogonDialog() or Logon(UserName, password, CMS, authenticationMode). In the end the program should quit the Designer, otherwise the designer.exe will stay running, even when your program finished. For this reason, your code should handle possible exceptions and quit the application before quiting the program.

using System;
using Designer;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Application application = new Application();
            try
            {
                application.LogonDialog(); 

                // ... some code here ...
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            finally
            {
                application.Quit();
            }
        }
    }
}

Hello Universe!

The following program imports the standard universe “Island Resorts Marketing” and prints the structure of its classes.

using System;
using Designer;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Application application = new Application();
            try
            {
                application.LogonDialog();
                Universe universe =
                    application.Universes.OpenFromEnterprise(
                        "webi universes",
                        "Island Resorts Marketing",
                        false);
                Console.WriteLine(universe.Name);
                PrintClasses(universe.Classes, 3);
                universe.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            finally
            {
                application.Quit();
            }
        }

        static void PrintClasses(Classes classes, int indent)
        {
            foreach (Class theclass in classes)
            {
                Console.WriteLine(
                    new String(' ', indent)
                    + theclass.Name
                    + " [" + theclass.Objects.Count
                    + " objects, "
                    + theclass.PredefinedConditions.Count
                    + " conditions]");
                PrintClasses(theclass.Classes, indent + 3);
            }
        }

    }
}