Purpose of SDK in Business Objects?

Hello All

I am just getting more involved with Business Objects so please excuse the very basic question.

I know what a SDK is and understand that it allows developers to make certain applications for BO Software. For the BO professionals here, in what ways have you used the SDK? What add-ons were you able to create? What are some general purposes of this sdk?


KennyBo :uk: (BOB member since 2010-07-13)

We used the admin SDK to automate user and group maintenance - read updates from a database, add and delete user info.

Another “classic” is calling reports from a JSP application external to the BO Infoview interface.

Good luck!
B


bdouglas :switzerland: (BOB member since 2002-08-29)

Oh, boy. We’ve created a ton of stuff using the SDK. Some ad-hoc, some used every day. Examples:[list][:b687483769]Automatically create BOE user IDs for new users
[
:b687483769]Monitor health of WebI services and web servers
[:b687483769]Monitor scheduled report activity
[
:b687483769]Web page to show any and all BO environments in which a specified user ID exists
[:b687483769]Web page to list all users in a group and subgroups
[
:b687483769]“BCA Console”-type view for end-users in Infoview
[:b687483769]Programmitcally modify WebI reports to adjust for changes to openDocument.jsp location in XI3
[
:b687483769]Web page to create users with our preferred default preferences
[:b687483769]Generate a map showing FRS usage by folder
[
:b687483769]Move reports from 6.5.1 Categories into XI3 Folders
[:b687483769]Load database tables with user/group info to enable reporting with audit data
[
:b687483769]Save a batch of WebI reports in Excel format by CUID, to ease the task of QA’ing version upgrades
…lots more
[/list]
Joe


joepeters :us: (BOB member since 2002-08-29)

Joe,

Please can you share all the samples, As am intrested in SDK stuff and thought to start on creating Users from Application.

Implemented couple:

  • Dynamically apply/update restriction sets (Row level) from the application drop down selection.
  • Bypass the BO login page and also BO Home page and display query panel page.

Thanks
Satya


Satya Vooturi :india: (BOB member since 2009-01-15)

No. Maybe in due time, but there’s a lot of stuff in each script that I’d have to strip out and clean up before posting. If you’re specifically interested in one or two, I can do that.


joepeters :us: (BOB member since 2002-08-29)

Wow - that’s a hefty library - good stuff.


Atul Chowdhury (BOB member since 2003-07-07)

You can also check out BOInterface (http://www.mnsoft.org/bointerface0.0.html) - it is not free, which is why I don’t talk about this very often here. But the Javadoc (http://www.mnsoft.org/boxinterfacedocs/) may give you some guidance on what it can do.


M :de: (BOB member since 2003-11-25)

I’ve done a number of things with the SDK:

  • User license auditing program that shows the relationships between users, group, and reports as well as the last time the user logged in to the system. (NOTE: I will be doing a session on this program at the ASUG conference in Orlando in October.)
  • Programs to schedule reports or publish files that are run from a batch processing system.
  • A program to maintain add and delete users as well as update their group assignments.
  • A report archive system.

I used to have a website with C#.NET sample and tutorial code that was on Geocities, but that went away when Geocities died. I’m in the process of putting together a new site, but it’s not up and running yet.

-Dell


hilfy :us: (BOB member since 2007-04-16)

Joe,
Can you please share the application “Move reports from 6.5.1 Categories into XI3 Folders” if possible

Thanks


ashwin84 (BOB member since 2010-08-18)

We have a requirement to implement the write back option in WebI XI 3.1.

Write Back option:

End User will enter their comments on seeing the Product data in report. That comments has to be stored in the data base. When the user runs the report for the next time , Product data should get reflected along with the user entered comments.

Is it possible to achieve the same Using SDK? Or let me know if other oprtion available for this…

Thanks in Advance


simi (BOB member since 2007-10-09)

I believe what you are describing is this. Let me know if I’m wrong.

http://www.sdn.sap.com/irj/boc/innovation-center?rid=/webcontent/uuid/00943325-26fd-2b10-3492-c0608c5ea93d


Bolandb (BOB member since 2010-06-08)

Yup; attached.

Joe
MoveCat.zip (2.0 KB)


joepeters :us: (BOB member since 2002-08-29)

Hye everyone ,

Where do you install the SDK ? ( Consider BO server & Java / .Net application services are running on different machines )
What 's the role of BO guys ? Is he the one to write the code or it is done with the help of web programmers ?
How should one start learning SDK ? where can i find the documentation ?

I appreciate your help on this . Thanks a lot


cynosure (BOB member since 2011-10-05)

The SDK is really just a bunch of library files. They are installed automatically along with the desktop tools (DeskI/Designer). You’ll find them in c:\program files\business objects\common

Depends on the guy :slight_smile: I write SDK code.

You’ll find the Java documentation here, and sample code on the recently-disorganized SCN site here.

Joe


joepeters :us: (BOB member since 2002-08-29)

Joe:
In the past I’ve created a bunch of macros inside Deski report, excel or asp pages to split a reports by section then send email in PDF, Universe and report documentation and archive (before Xi), but for some reason I never thought would be possible to create a the ones listed below. Those tasks are the most common that I usually do and take a lot of time from me. Could you share it, whenever you got time available?

For C, I wonder what it does, It does tell you the % of disk usage by disk folder or relate the disk usage by InfoView folder?

a) Web page to list all users in a group and subgroups
b) Monitor scheduled report activity
c) Generate a map showing FRS usage by folder

Thanks in advance
Reinaldo


reinaldonunez :venezuela: (BOB member since 2004-10-01)

I can give you the important parts of a and c.

Get users:

<%!
	// getgroups: 	generates HTML-formatted string containing all users and groups
	//				below the selected group ID
	//				Calls itself to recurse through all child groups
	public String getgroups(Integer si_id,IInfoStore oInfoStore,int iLevel)
	{
		String strHTML = "";
		Date sendDate;


		// Increment iLevel; abort if we get beyond 12 levels (to ensure we don't get stuck in a loop)		
		iLevel += 1;
		if(iLevel > 12)
		{
			strHTML += "<tr><td colspan=3>Returning for: " + si_id + "</tr>";
			return strHTML;
		}
		
		// First part of string -- level number of current group	
		strHTML = "<tr><td>&amp;nbsp;</td></tr>";
		strHTML += "<tr><td>Level: " + iLevel + "</td>";
		
		try {
			// This call gets the first (only) item in the list -- note that it is getting the PARENT 
			// group, not the subgroups
			IInfoObject myUserGroup = getIoBySQL(oInfoStore," SELECT SI_SUBGROUPS,SI_ID,SI_GROUP_MEMBERS FROM  CI_SYSTEMOBJECTS WHERE  SI_ID = " + si_id);

			// Display the parent group name
			strHTML +=  "<td>" + myUserGroup.getTitle();

			// Now we create an array (subUsers) containing the users of the parent group
			// ..and add user into into the HTML string
			Object[] subUsers = ((IUserGroup)myUserGroup).getUsers().toArray();
			strHTML += "<td>" + (subUsers.length) + " Users" + "</tr>"; 

			for (int x = 0; x < subUsers.length; x++) 
			{
				IInfoObject oISUser = getIoBySQL(oInfoStore," SELECT si_name,SI_USERFULLNAME,SI_CREATION_TIME FROM  CI_SYSTEMOBJECTS WHERE si_id = " + subUsers[x]);
				String strFullName;

				sendDate = (Date)oISUser.properties().getProperty("SI_CREATION_TIME").getValue();
				String newdate = new SimpleDateFormat("MM/dd/yy hh:mm:ss a").format(sendDate);
				
				if (!(oISUser.properties().getProperty("SI_USERFULLNAME") == null))
					strFullName = (String)oISUser.properties().getProperty("SI_USERFULLNAME").getValue();
				else
					strFullName = " ";
				
				strHTML += "<tr><td>" + (oISUser.getTitle() + "</td><td>" + newdate + "</td><td>" + strFullName + "</td><td>" + "</tr>");
			}


			// Create another array to contain the group's subgroups
			Object[] subgroups = ((IUserGroup)myUserGroup).getSubGroups().toArray();
			
			for (int x = 0; x < subgroups.length; x++) 
			{
				//strHTML += (subgroups[x] + "<BR>");
				int myval = ((Integer)subgroups[x]).intValue();
				Integer myInt = new Integer(myval);
				
				// Recursively call getgroups for each member of the parent group
				strHTML += getgroups(myInt,oInfoStore,iLevel);
			}
		} 
		catch (SDKException e) {
		}
		return (strHTML);		
	}
%>

and for c. This presents the percentage of the parent folder, and of all content (not considering disk space)

	out.print ("<table border=1 style='font-size: small;font-family: courier;'>");
	
	IInfoObjects myoInfoObjects;
	DateFormat dateFormatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM);
	
	//Execute the query
	myoInfoObjects = oInfoStore.query("select top 10000 si_id,si_name from ci_infoobjects where si_parentid in (" + strIt + ") and si_id != 23 order by si_name");

	ArrayList aList = new ArrayList();
	
	aList.add("Top");
	aList.add(new Long(0));  // file space
	aList.add(new Long(1));  // file count
	
	for (int x = 0; x < myoInfoObjects.size(); x++)
	{
		IInfoObject oInfoObject = (IInfoObject)myoInfoObjects.get(x);
	
		if (!oInfoObject.getTitle().equals ("Categories") &amp;&amp; !oInfoObject.getTitle().equals ("Personal Categories")) {

			Integer duh  = new Integer(oInfoObject.getID());

			aList.add(getgroups(duh,oInfoStore,0,oInfoObject.getTitle()));
		}
	}
	aList.set(1,setSizeAndSort(aList,0));
	setCount(aList,0);
	
	out.print (getTheArray(aList,0,"",((Long)aList.get(1)).longValue(),((Long)aList.get(1)).longValue()));
	out.print ("</table>");
%>

<%!	
	ArrayList getgroups(Integer si_id,IInfoStore oInfoStore,int iLevel,String fullFolder)
	{
		ArrayList aList = new ArrayList();
		
		// Add the name to the array
		aList.add(fullFolder);

		// Increment iLevel; abort if we get beyond 12 levels (to ensure we don't get stuck in a loop)		
		iLevel += 1;
		if(iLevel > 100)
			return aList;

		try {
			IInfoObjects ioInnerFiles = null;
			IInfoObjects ioInnerFolders = null;

			// Get this folder's deski/webi files
			ioInnerFiles = oInfoStore.query(" SELECT top 10000 si_files,si_id,si_name,si_kind from ci_infoobjects where si_kind in ('fullclient','webi') and si_parentid = " + si_id + " and si_name != 'User Folders' order by si_name");
		
			long lSize = 0;
			for (int x = 0; x < ioInnerFiles.size(); x++) 
			{
				IInfoObject oISFile = (IInfoObject)ioInnerFiles.get(x);
				
				try 
				{
					IFiles files = oISFile.getFiles();
		
					for (int county = 0; county < files.size(); county++) {
						IFile file = (IFile)files.get(county);
						
						lSize += file.getSize();
					}
				}
				catch (Exception wtf) {}; // ignore errors when getting Files
			}
			aList.add(new Long(lSize));
			aList.add(new Long(ioInnerFiles.size()));
			
			
			// Get the children of this group
			ioInnerFolders = oInfoStore.query(" SELECT top 10000 si_files,si_id,si_name,si_kind from ci_infoobjects where si_children > 0 and si_parentid = " + si_id + " order by si_name");
		
			for (int x = 0; x < ioInnerFolders.size(); x++) 
			{
				IInfoObject oISFolder = (IInfoObject)ioInnerFolders.get(x);
				
				ArrayList aTemp;
				
				Integer theID = new Integer(oISFolder.getID());
				aTemp = getgroups(theID,oInfoStore,iLevel,fullFolder + " / " + oISFolder.getTitle());
				
				aList.add(aTemp);
			}
		} 
		catch (SDKException e) {	
			System.out.print (e);
		}
		return aList;
	}

	String formatPercent(float one,float two)
	{
		if(two == 0)
			return "-";
		
		NumberFormat f = NumberFormat.getPercentInstance();  
		f.setMinimumFractionDigits(1);  
		f.setMaximumFractionDigits(1);
		return f.format(one / two);
	}

	String formatNumber(long  inNum)
	{
	    NumberFormat formatter = new DecimalFormat("###,###,###,###");
	    String s = formatter.format(inNum);
	    
	    return s; 
	}

	String formatNumber(Long  inNum)
	{
		return formatNumber(inNum.longValue());
	}

	String getTheArray(ArrayList aList,int iLevel,String strSpace,long parentSize,long topSize)
	{
		if(aList.size() == 0)
		{
			return "";
		}
		String strString = "";
			
		if( ((Long)aList.get(1)).longValue() > 0)
		{
			strString = "<tr><td>" + formatNumber(iLevel) + 
							   "</td><td>" + strSpace + aList.get(0) + 
							   "</td><td align=right>" + formatNumber((Long)aList.get(1)) + 
							   "</td><td align=right>" + formatPercent( ((Long)aList.get(1)).longValue(),parentSize) +
			   				   "</td><td align=right>" + formatPercent( ((Long)aList.get(1)).longValue(),topSize) +
			   				   "</td><td align=right>" + formatNumber((Long)aList.get(2)) + "</td></tr>";
			
			for(int i = 3;i < aList.size();i++)
			{
				strString += getTheArray((ArrayList)aList.get(i),iLevel+1,strSpace + "&amp;nbsp;&amp;nbsp;",((Long)aList.get(1)).longValue(),topSize);
			}
		}
		return strString;
	}

	Long setSizeAndSort(ArrayList aList,int iLevel)
	{
		Long mySize;
		mySize = (Long)aList.get(1);

		// First, recurse - this makes sure the Total Size is set at the lower levels
		for(int i = 3;i < aList.size();i++)
			mySize = new Long ( mySize.longValue() + setSizeAndSort((ArrayList)aList.get(i),iLevel+1).longValue());
		
		// Now sort
		for(int i = 3;i < aList.size();i++)
			for(int j = i+1;j < aList.size();j++)
			{
				if( ((Long)((ArrayList)aList.get(j)).get(1)).longValue() > ((Long)((ArrayList)aList.get(i)).get(1)).longValue())
				{
					ArrayList aTemp = (ArrayList)aList.get(i);
					aList.set(i, aList.get(j));
					aList.set(j,aTemp);
					
				}
			}
		aList.set(1,mySize);
		
		return mySize;
	}

	long setCount(ArrayList aList,int iLevel)
	{
		long myCount;
		myCount = ((Long)aList.get(2)).longValue();

		// First, recurse - this makes sure the Total Count is set at the lower levels
		for(int i = 3;i < aList.size();i++)
			myCount += setCount((ArrayList)aList.get(i),iLevel+1);
		
		aList.set(2,new Long(myCount));
		
		return myCount;
	}

joepeters :us: (BOB member since 2002-08-29)

Thanks Joe, those may come pretty handy. I will try to reproduce it, hopefully get good results. Thanks a lot!!!


reinaldonunez :venezuela: (BOB member since 2004-10-01)

Hi Joe,

Please can you share the code of how you used SDK to monitor how many

Scheduled a report or their execution time,

Thanks a lot.


yeni (BOB member since 2013-02-08)

Hello Joe,

I am also very much interested on monitoring the scheduled reports.

kindly share the excel macro file.

Thanks,


Tims_Bo :india: (BOB member since 2008-07-26)

It’s not Excel – it’s a JSP application that I built. I will need to do a lot of clean-up in it before it’s ready to be posted here.


joepeters :us: (BOB member since 2002-08-29)