您的位置:首页 > 产品设计 > UI/UE

Querying the InfoStore

2013-10-18 10:45 323 查看

Querying the InfoStore

For
most everything else that cannot be invoked from the EnterpriseSession object, you need to query the InfoStore first. This includes creating objects, scheduling them, updating them, or simply retrieving them.
InfoStore objects include reports, users, groups, folders, categories, dashboards, schedules, license keys, server registrations, Universes, and Business Viewsevery bit of information that is presented through the portal and which the system
needs to function. Regardless of type, they are all InfoObjects that implement the InfoObject interface. Every InfoObject has certain common properties, such as an ID, name, and kind. Other properties are stored as name-value pairs in a property bag datastructure.
Objects are all stored physically in the Business Objects repository database in both primitive (common properties) and composite binary fields (the rest of the bag). If you like, you can inspect the CMS_InfoObjects4 table in a database browser.
The model is highly denormalized for performance. In BusinessObjects Enterprise XI, additional tables were added to speed up alias and hierarchy access associated with the inclusion of many-to-many object categorization in the design.

Note
Did you know that the original Seagate Info had more than 20 physical tables? Its successor, Crystal Enterprise 8.0, implemented a new InfoStore service that made much greater use of binary fields in the database and eliminated reliance on
database-enforced referential integrity. Smart engineers in Vancouver found that performance increased considerably and that linear scalability was now attainable.

Now that you understand that certain properties are represented physically and indexed in the database and others are buried in binary fields, please forget that there is a physical database behind InfoStore. You will never access this or
any of the other tables in the system directly. Rather, you will retrieve objects using an SQL-style syntax executed against an API object called the InfoStore.
The statement below returns a list of all user-names in the system. This code snippet, like others in this chapter, assumes that valid local IInfoStore (iStore) and EnterpriseSession (es) instances have been instantiated.

IInfoObjects objs=iStore.query('SELECT SI_NAME FROM CI_SYSTEMOBJECTS WHERE  SI_KIND='USER'')


Under the covers, the Central Management Server (CMS) service sometimes runs a query against the physical tables, but more often it runs a query against in-memory datastructures it maintains as the system is used.

Note
If
you want to speed up your InfoStore queries, you can put a loop in your application initialization code that requests a bunch of the objects from the InfoStore. There are obviously short-term performance implications in doing this.

The InfoStore functions much like an object-relational persistence tier with its own proprietary methods of accessing and updating objects. Here are some unusual characteristics that will help you understand some of the other examples in
this chapter and the product documentation:

Everything is an IInfoObject The InfoStore contains many objects of many types or classes. However, they all inherit from the common
IInfoObject class that permits them to be queried and persisted in a common manner and allows them to share certain common properties and methods.
Casting is the conversion of one data type to another. When retrieving an
IInfoObject object, it is sometimes necessary to cast it to a more specific object type, such as IReport. At a minimum, when iterating through IInfoObjects returned by an InfoStore query, objects must be cast to an
IInfoObject.

Creating an object with Plugins When you create an object, you won't find a
CreateThisTypeOfObject() method in the API. Rather, you need to look up the object type in the InfoStore and first get a reference to a system object called the Plugin interface. Similarly, if you want to schedule to a destination such as e-mail, you
must get a destination plugin from the InfoStore. This design is flexible, in that new object types and destinations may be added without affecting the API, but it can be awkward to use.

Embedded objects Certain objects have what appear to be embedded objects. Job scheduling or report processing objects are accessed from their container objects through the
SI_SCHEDULEINFO and SI_PROCESSINFO properties respectively. For instance,
iStore.query("SELECT SI_SCHEDULEINFO FROM CI_INFOSTORE WHERE SI_NAME='World Sales Report'") will return each of the schedules created for the World Sales Report. Embedded objects, such as scheduling or processing information, must be cast before they
can be accessed.

Committing changes to objects There is, in fact, no way to commit changes to one object. Every change to an InfoStore object starts with selecting
all objects that meet certain criteria, iterating through the collection, modifying one or more InfoObject, and then committing
all of the originally retrieved objects to the InfoStore.

Knowing what types of objects and their properties that are available for selection and/or for filtering the InfoStore will help you understand what you can do with BusinessObjects Enterprise. These topics are covered next.

BusinessObjects Enterprise Categories, Kinds, and Casting

InfoStore objects live virtually in one of three categories which are accessed in the FROM clause of an InfoStore query. Different types of objects belong to different categories. In fact, several objects, such as
Folder, belong to more than one category. In BusinessObjects
Enterprise
XI you no longer need to use the CI_PROGID identifier to find a certain type of object, but rather you use the more friendly
CI_KIND property. Kinds can be accessed literally or through the com.crystaldecisions.sdk.plugin.CeKinds enumeration. Note that sometimes the enumerated constant is not the same as the literal value. The following query string will return
no values:

[View full width]IInfoObjects objs=iStore.query('SELECT TOP 1 FROM CI_INFOOBJECTS WHERE


SI_KIND='CRYSTAL_REPORT'');

These two, however, will work:

[View full width]IInfoObjects objs=iStore.query('SELECT TOP 1 FROM CI_INFOOBJECTS WHERE SI_KIND=''+ com


.crystaldecisions.sdk.plugin.CeKinds.CRYSTAL_REPORT+'');
IInfoObjects objs=iStore.query('SELECT TOP 1 FROM CI_INFOOBJECTS WHERE


SI_KIND='CrystalReport'');

This is because the literal value "CRYSTAL_REPORT" is not a
SI_KIND. However, com.

crystaldecisions.sdk.plugin.CeKinds.CRYSTAL_REPORT evaluates to 'CrystalReport'.


Tables 30.430.7 list what
kinds of objects can be found in each category, as well as the interface objects to which they must be cast for all of their properties to be accessible. Certain object types specific to the Application Foundation and Performance Management suite of products
are unpublished.

Table 30.4. CI_INFOOBJECTS Kinds

SI_KIND Value

CeKind Enumeration

Interface

AFDashboardPage

AFDASHBOARDPAGE

Unpublished

Analytic

ANALYTIC

Unpublished

Category

CATEGORY

ICategory

CrystalReport

CRYSTAL_REPORT

IReport

Excel

EXCEL

IExcel

FavoritesFolder

FAVORITESF

IFolder

Folder

FOLDER

IFolder

Hyperlink

HYPERLINK

IHyperlink

Inbox

INBOX

IInbox

MyInfoView

MYINFOVIEW

Unpublished

ObjectPackage

OBJECTPACKAGE

IObjectPackage

Pdf

PDF

IPDF

PersonalCategory

PERSONALCAT

ICategory

Powerpoint

POWERPOINT

IPowerpoint

Program

PROGRAM

IProgram

Shortcut

SHORTCUT

IShortcut

Txt

TEXT

ITxt

Webi

WEBI

IWebi

Word

WORD

IWord

Table 30.5. CI_SYSTEMOBJECTS Kinds

SI_KIND Value

CeKind Enumeration

Interface

Calendar

CALENDAR

ICalendar

Connection

CONNECTION

IConnection

Event

EVENT

IEvent

LicenseKey

LICENSEKEY

ILicenseKey

Server

SERVER

IServer, IServerGeneralMetrics

User

USER

IUser

UserGroup

USERGROUP

IUserGroup

Table 30.6. CI_APPOBJECTS Kinds

SI_KIND Value

CeKind Enumeration

Interface

AppFoundation

APPFOUNDATION

Unpublished

CMC

CMC

Unpublished

Designer

DESIGNER

Unpublished

Discussions

DISCUSSIONS

Unpublished

InfoView

INFOVIEW

Unpublished

StrategyBuilder

STRATEGY_BUILDER

Unpublished

Universe

UNIVERSE

IUniverse

WebIntelligence

WEBINTELLIGENCE

IWebi

Table 30.7. Other Object Kinds

SI_KIND Value

CeKind Enumeration

Interface

Destination

DESTINATION

IDestination

DiskUnmanaged

DISKUNMANAGED

IDiskUnmanaged

Ftp

FTP

IFTP

Managed

MANAGED

IManged

Overload

OVERLOAD

IOverload

Rtf

RTF

IRTF

secEnterprise

SEC_ENTERPRISE

IsecEnterprise

secLDAP

SEC_LDAP

IsecLDAP

secWinAD

SEC_WINAD

IsecWinAD

secWindowsNT

SEC_WINDOWSNT

IsecWinNT

ServerGroup

SERVER_GROUP

IServerGroup

Smtp

SMTP

ISMTP

Although not shown, Folder objects can be referenced from all three table contexts.

CI_INFOOBJECTS Contains portal content

CI_SYSTEMOBJECTS
Contains
system objects required for the system to function and that are displayed and managed in the user interface

CI_APPOBJECTS Other objects stored in the repository but managed through client-server tools or add-ons to the system

Several other kinds of objects require more sophisticated query statements to access. They include destination and security plugins.

BusinessObjects Enterprise Object Properties

Object properties are discussed next,
organized first by common, indexed properties, and then by the types of objects or functions for which they are used. These properties can be found in the CePropertyID enumerated list and a complete list can be found in the SDK documentation itself. Usage
notes are provided inline and several of the more commonly used ones will reappear in the sections and samples that follow.

Property Bags
All InfoObject propertiesboth indexed and nonindexedare accessible from the object's property bag interface,
properties(). These properties are accessed with their CePropertyID identifier as shown here:

//get the object
IInfoObject obj=(IInfoObject)objs.get(0);
//get the SI_INSTANCE property
int SI_INSTANCE =obj.properties().getProperty(CePropertyID.SI_INSTANCE). getValue();


However, certain indexed properties have direct accessor methods as noted. For instance,
getID() saves a few keystrokes on obj.properties().getProperty(CePropertyID.SI_ID).getValue(). Should you want to list everything in an IInfoObject, you could use call a function to recursively display the object property bags. This is such
a useful function that it is provided in
Listing 30.1 in its entirety.

Listing 30.1. Recursively Listing IInfoObject Properties

public static String infoObjectToString(IInfoObject obj){
return propertyBagToString(obj.properties());
}
public static String propertyBagToString(IProperties propMap) {
return propertyBagToString(propMap,"");
}
private static String propertyBagToString(IProperties propMap,String  prefix) {
StringBuffer buff = new StringBuffer();
buff.setLength(0);
if ((propMap != null) && (propMap.size() > 0)) {
Iterator iter = propMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry p = (Map.Entry) iter.next();
Integer id=(Integer)p.getKey();
buff.append(prefix+CePropertyID.idToName(id));
IProperty prop=(IProperty)p.getValue();
if (prop.isContainer()){
IProperties props=(IProperties)prop.getValue();
buff.append("\n");

buff.append(propertyBagToString(props,prefix+CePropertyID.idToName(id)+"."));
} else {
buff.append("="+prop.getValue()+"\n");
}
}
}
return buff.toString();
}

This function returns property objects that fall into one of three categories:

Top-level properties that contain values such as strings and integers

Composite properties that contain other properties that require casting

Composite properties that actually represent embedded objects with their own identifiers in the system

The SI_SCHEDINFO property, for instance, contains a collection of job objects that spawn new instances on a schedule.

Listing 30.2 shows many of the properties for the Product Category report, which has not been assigned to any corporate or personal categories, scheduled, or had its default processing options modified; Microsoft Access requires none and the system default
printer is assigned by default. The listing shows the output properties for the Product Catalog sample report shipping with BusinessObjects Enterprise. Properties such as
SI_FILE are composite properties. There are no embedded objects in this listing as the report has not been scheduled.

Listing 30.2. Product Catalog Report Property Listing

[View full width]
SI_APPLICATION_OBJECT=false
SI_AUTHOR=Copyright © 2004 Business Objects
SI_BUSINESSVIEWS
SI_BUSINESSVIEWS.SI_TOTAL=0
SI_CHILDREN=28
SI_COMPONENT=false
SI_CORPORATE_CATEGORIES
SI_CORPORATE_CATEGORIES.SI_TOTAL=0
SI_CREATION_TIME=Mon Dec 06 17:58:25 PST 2004
SI_CUID=AaCbu62TlMdDo60E358dydA
SI_DESCRIPTION=Product catalog, grouped by Product Class, Product Type and  Product Name
with Product Type picture and description. Drill down on  Product Name for item numbers,
sizes, etc.
SI_FILES
SI_FILES.SI_FILE1=~ce14483a4783797718.rpt
SI_FILES.SI_FILE2=~ce14483a478383d719.jpeg
SI_FILES.SI_NUM_FILES=2
SI_FILES.SI_PATH=frs://Input/a_194/024/000/6338/
SI_FILES.SI_VALUE1=728064
SI_FILES.SI_VALUE2=23015
SI_FLAGS=2050
SI_GUID=AbzQfLTci61CnFu8C6sIH3Y
SI_HASSAVEDDATA=false
SI_HASTHUMBNAIL=true
SI_HIDDEN_OBJECT=false
SI_ID=6338
SI_INSTANCE_OBJECT=false
SI_INSTANCE=false
SI_IS_SCHEDULABLE=true
SI_KIND=CrystalReport
SI_LAST_RUN_TIME=Fri Feb 18 14:25:09 PST 2005
SI_LAST_SUCCESSFUL_INSTANCE_ID=32052
SI_NAME=Product Catalog
SI_OBJECT_IS_CONTAINER=false
SI_OBTYPE=2
SI_OWNER=Administrator
SI_OWNERID=12
SI_PARENT_CUID=ARD1V.IRaKdPs3fPUzttR3k
SI_PARENT_FOLDER_CUID=ARD1V.IRaKdPs3fPUzttR3k
SI_PARENT_FOLDER=6322
SI_PARENTID=6322
SI_PERSONAL_CATEGORIES
SI_PERSONAL_CATEGORIES.SI_TOTAL=0
SI_PLUGIN_OBJECT=false
SI_PROGID=CrystalEnterprise.Report
SI_REFRESH_OPTIONS=-2
SI_RUID=AaCbu62TlMdDo60E358dydA
SI_RUNNABLE_OBJECT=false
SI_SENDABLE=true
SI_SYSTEM_OBJECT=false
SI_TABLE=0
SI_TOPIC_TOPIC_FOR_SUBJECT_GENERICENTITY
SI_TOPIC_TOPIC_FOR_SUBJECT_GENERICENTITY.SI_TOTAL=0
SI_TURNONREPOSITORY=false
SI_TURNONTHUMBNAIL=true
SI_UPDATE_TS=Fri Feb 18 14:25:09 PST 2005

Indexed Properties
Every
property in the property bag can be supplied in the SELECT clause (but not necessarily in the WHERE clause) of an InfoView query. Embedded object properties make no sense in the WHERE clause, but the full path to embedded object properties might. Querying
for IInfoObjects WHERE SI_FILES.SI_NUM_FILES > 1 is a bogus, but valid, example. However, when querying the InfoStore, it is vital to include at least one common, indexed property to help reduce the working set. These properties exist physically in
the repository database and can be queried at will without degrading system performance. Filtering exclusively on a nonindexed property forces the InfoStore API to open and examine every object in the InfoStore table to find a match. Such fields must be read,
parsed, and loaded into the InfoStore memory cache before they can be used by the system, which can take time and precious CPU cycles.

Note
Don't worry about the order of fields in the WHERE clauseBusinessObjects Enterprise will reorder evaluation from indexed to nonindexed properties appropriately prior to execution.

Table 30.8 lists all of the indexed properties. The boolean properties
SI_HIDDEN_OBJECT, SI_NAMED_USER, and SI_PLUGINOBJECT are rarely used and have been omitted from this table. Certain job-specific properties might be null. Especially in Java, you must always test for nulls to avoid the dreaded and
never specific Null Pointer Exception. Code defensively!

Table 30.8. Indexed Properties

Property

Type

InfoObject Accessor Method

Description/Usage Notes

SI_ID

Integer

getID()

A sequence number unique to a single installation unless it is a common, default system object below 350. Remember that your code will not work if you hard-code an object's
SI_ID and then move that object from your development to test to production environments.

SI_CUID

String

getCUID()

A string identifier, unique and consistent across all environments. Migration safe.

SI_GUID

String

getGUID()

Reserved for future use.

SI_RUID

String

getRUID()

A string identifier that uniquely identifies an InfoObject within an object package. Outside of a package, it is equivalent to
SI_CUID.

SI_NAME

String primitive

getTitle()

Object name or title. Note that instances and jobs share the same name. It is typically insufficient to query on
SI_NAME alone.

SI_KIND

String

getKind()

New to BusinessObjects Enterprise XI, this property replaces
SI_PROGID as the preferred method for retrieving objects of a certain type (as discussed above).

SI_DESCRIPTION

String

getDescription()

Longer description.

SI_PROGID

String

getProgID()

The internal object type identifier. For example, CrystalEnterprise.CrystalReport.

SI_OWNERID

Integer

getOwnerID()

The owner of this object. Particularly useful when trying to find a user's recurring or one-time job schedules or historical instances they have created.

SI_PARENTID

Integer

getParentID()

The parent of this object. For report templates, this refers to the parent folder. For report instances,
SI_PARENTID points to the report template rather than the containing folder. The noninteger property
SI_PARENT_FOLDER is the best way to finds an instance's folder.

SI_UPDATE_TS

Timestamp

Property bag

The last time any property of the object was modified. Date is returned in the format MM/DD/YYYY HH:MM:SS AM/PM. In the WHERE clause, these formats are valid: yyyy.mm.dd.hh.mm.ss, yyyy/mm/dd/hh/mm/ss, yyyy/mm/dd.hh.mm.ss, yyyy/mm/dd,hh:mm:ss.
For example, SELECT SI_ID, SI_NAME FROM CI_INFOOBJECTS WHERE SI_UPDATE_TS > '2000.01.11.18:00:00'.

SI_INSTANCE, SI_INSTANCE_OBJECT

Boolean 1/0

Property bag

Specifies whether to retrieve the report/document or an historical instance run by the scheduler as a job.

SI_NEXTRUNTIME

Timestamp

Property bag

Nullable. The next time that one of the job servers will attempt to create an instance. See usage notes for
SI_UPDATE_TS.

SI_RECURRING

Boolean 1/0

Property bag

May be null. For job/schedule embedded objects, indicates whether a job will run more than once.

SI_RUNNABLE_OBJECT

Boolean 1/0

Property bag

May be null. Crystal Reports, Web Intelligence, Program Objects, and Object Packages can be scheduled. To be runnable, such an object must actually be scheduled to run and create an instance.

SI_SCHEDULE_STATUS

Integer

Property bag

May be null. Status of a runnable object. Constantly requires decoding using the ceScheduleStatus enumeration.

Composite Properties, Embedded Objects
As discussed earlier, certain properties contain other properties and, in the
case of SI_SCHEDINFO, have identifiers that permit individual retrieval and manipulation. A simple example is that
SI_PATH, which is for folder objects, returns the property bag that includes the IDs, names, and types of every folder ancestor for the object. The function
folderBreadCrumbs(String folderID, IInfoStore iStore) found in BOEUtil.java on

www.usingcrystal.com shows how this is used.
Table 30.9 highlights some other composite properties that contain both primitive and composite values. Subproperties can be queried
using dot notation. For instance, the following code retrieves the names of all the users who scheduled the World Sales Report.

[View full width]String sql = ' SELECT SI_SCHEDULEINFO.SI_SUBMITTER FROM CI_INFOOBJECTS  WHERE


SI_NAME='World Sales Report'';
IInfoObjects objects = iStore.query(sql);

Table 30.9. Composite Properties (Incomplete List)

Composite Property

Sample Property Values (Vary Based on Data)

Embedded Object Properties

SI_SCHEDULEINFO
Returns multiple schedule (job) objects associated with an InfoObject or the schedule object itself (if accessed directly).

SI_ENDTIME=Wed Mar 16 00:00:00 PST 2005
SI_NAME=Product Catalog
SI_OBJID=31747
SI_OUTCOME=0
SI_PROGRESS=1
SI_RETRIES_ALLOWED=0
SI_RETRIES_ATTEMPTED=0
SI_RETRY_INTERVAL=1800
SI_SCHED_NOW=false
SI_SCHEDULE_INTERVAL_HOURS=0
SI_SCHEDULE_INTERVAL_MINUTES=0
SI_SCHEDULE_INTERVAL_MONTHS=0
SI_SCHEDULE_INTERVAL_NDAYS=0
SI_SCHEDULE_INTERVAL_NTHDAY=0
SI_SCHEDULE_TYPE=8
SI_STARTTIME=Wed Feb 16 18:13:00 PST 2005
SI_SUBMITTER=Administrator
SI_SUBMITTERID=12
SI_TIMEZONE_ID=0
SI_TYPE=2
SI_UISTATUS=9

SI_DEPENDANTS
SI_DEPENDENCIES
SI_DESTINATION
SI_RUN_ON_TEMPLATE

SI_PROCESSINFO
Contains report processing directives.

SI_DBNEEDLOGON=true
SI_DEPENDS_ON_CIV=false

SI_ALERT_INFO
SI_BUSINESS_VIEW_INFO

 

SI_DEPENDS_ON_METADATA=false
SI_GROUP_FORMULA=
SI_HAS_DCP=false

SI_FILES
SI_FORMAT_INFO
SI_HYPERLINK_INFO

 

SI_NAME=Statement of Account
SI_NUM_GROUPS=2
SI_OBJID=6333
SI_RECORD_FORMULA={Orders.Order Amount}>0 and {Orders.Shipped}=Yes and not {Orders.Payment Received}
SI_RFSH_HITS_DB=true
SI_ROW_LEVEL_SECURITY=false
SI_SESSION_NEEDINFO=false
SI_SESSION_USER=
SI_SHARE_INTERVAL=300
SI_SHARE_SETTINGS=false
SI_SHARE=true
SI_USES_FILE_DB=false

SI_LOGON_INFO
SI_PRINTER_INFO
SI_PROMPTS
SI_REPOSITORY_OBJECTS

SI_PATH
Ancestor folders.

SI_FOLDER_OBTYPE1=1
SI_FOLDER_ID1=6319
SI_FOLDER_NAME1=Report Samples
SI_NUM_FOLDERS=1

SI_FILES
Path to file report template and thumbnail in the File Input Server.

SI_FILE1=~ce14483a4783797718.rpt
SI_FILE2=~ce14483a478383d719.jpeg
SI_NUM_FILES=2
SI_VALUE1=728064
SI_VALUE2=23015

 

For more information on these composite properties, consult the documentation and use the property bag recurser function to explore them yourself.

Property Enumerations
In
Listing 30.3 and in ones that follow, property values are represented as numeric constants or codes. Fortunately, there is an easy way to decode these valuesthe static method on CePropertyID called
idToName(java.lang.Integer id). This function will work for every property, although you might want to write your own based on the appropriate SDK property enumeration.

Listing 30.3. Schedule Status Decoder

public static String getScheduleStatusDescription(int status) {
switch (status) {
case (ISchedulingInfo.ScheduleStatus.COMPLETE):
return "COMPLETE. Job completed successfully.";
<SNIP></SNIP>
default:
return "Status code not found";
}
}

Other
enumerations to familiarize yourself with include CeEvents, CeKind, and
CeScheduleType. Enumerations in the ISchedulingInfo interface include GroupChoice, ScheduleFlags, ScheduleOutcome, and ScheduleStatus. For a complete list of enumerations, please consult the API documentation.

Note
The etymology of the CI and
SI in table and property names might reflect the company heritage of the product, first in Seagate Software's Seagate Info, and then in Crystal Decisions, Crystal Enterprise. The
C could also stand for
Catalog. This kind of legacy name pollution is common in the software industry.

System Objects and Root Folders
As you get into more advanced SDK programming, it will help to know the addresses of well-known system objects and root folders. There are more than 100 such objects installed by default with BusinessObjects Enterprise. Only their enumerations
are listed here for brevity:

CeSecurityID.Folder The IDs of the BusinessObjects Enterprise system folders.

CeSecurityID.Limit The IDs of the BusinessObjects Enterprise system security limits.

CeSecurityID.Right The IDs of the BusinessObjects Enterprise system security rights.

CeSecurityID.User Common user and group IDs.

CeSecurityCUID.AppConfigObject Identifies the unique CUIDs that are used in a query to specify the application configuration components. Remember, these are in the CI_SYSTEMOBJECTS category.

CeSecurityCUID.Relation Identifies the unique CUIDs that are used in a query to retrieve related, dynamically generated objects.

CeSecurityCUID.RootFolder
Identifies the unique CUIDs that are used in a query to specify the root folder. The following SELECT statement can be used to return top level folders:

[View full width]       sql = "Select * FROM CI_INFOOBJECTS where SI_KIND = 'Folder' and


SI_PARENTID="+BOEUtil.getObjectByCUID(CeSecurityCUID.RootFolder.FOLDERS,"CI_INFOOBJECTS"


,iStore).getID();
objects = iStore.query(sql);

CeSecurityCUID.SystemObject Identifies the unique CUIDs that are used in a query to specify the system objects. Remember, these are in the CI_SYSTEMOBJECTS category.

Note
Please note that the identifiers provided in these enumerations are the CUID unique identifiers, not numeric identifiers. As a result, filters such as SI_ANCESTOR that expect a numeric ID will not work.
This statement fails:

[View full width]IInfoObjects objs=iStore.query("SELECT * CI_APPOBJECTS WHERE
SI_ANCESTOR=" + CeSecurityCUID.RootFolder.UNIVERSES + " AND SI_KIND='Universe' ORDER BY


SI_NAME");

However, this works:

[View full width]IInfoObjects objs=iStore.query("SELECT SI_ID CI_APPOBJECTS WHERE SI_CUID='" +


CeSecurityCUID.RootFolder.UNIVERSES+"'");
int UnvRootID=((IInfoObject)objs.get(0)).getID();
System.out.println("UnvRootID:"+UnvRootID);
IInfoObjects unvs=iStore.query("SELECT SI_ID, SI_NAME, SI_CUID FROM CI_APPOBJECTS WHERE


SI_ANCESTOR="+ UnvRootID+" AND SI_KIND='Universe' ORDER BY SI_NAME");

Remember, Universe objects are in the CI_APPOBJECTS category.

Certain system objects, unfortunately, are not in any enumeration. For instance, the only way to schedule objects to e-mail is to get a handle on an SMTP destination plugin, which is a child of the object known by its CUID as
CeSecurityCUID.SystemObject.PLUGIN. You can iterate through these children yourself and see that the SMTP destination plugin has an ID of 29.

Permissions
Another set of constants is the rights registered for each object type. Global security rights are in the CeSecurityID.Right enumeration. Certain objects cannot be scheduled, so schedule-oriented rights naturally do not apply to those objects.
System administrators will be familiar with the following enumerated rights from the CMC console:

CeSecurityID.Right ADD, COPY, DELETE, DELETE_INSTANCE, EDIT, MODIFY_RIGHTS, OWNER_DELETE, OWNER_DELETE_INSTANCE, OWNER_EDIT, OWNER_MODIFY_RIGHTS, OWNER_PAUSE_RESUME_SCHEDULE, OWNER_RESCHEDULE, OWNER_SECURED_MODIFY_RIGHTS,OWNER_VIEW,
OWNER_VIEW_INSTANCE, PAUSE_RESUME_SCHEDULE, PICK_MACHINES, RESCHEDULE, SCHEDULE, SCHEDULE_ON_BEHALF_OF, SECURED_MODIFY_RIGHTS, SET_DESTINATION, VIEW, VIEW_INSTANCE

CeReportRightID DOWNLOAD, EXPORT, PRINT, REFRESH_ON_DEMAND

CeWebiRightID DOWNLOAD_FILES, EDIT_QUERY, EXPORT_REPORT_DATA, REFRESH_LIST_OF_VALUES, RUN_AND_REFRESH_DOC, USE_LIST_OF_VALUES, VIEW_SQL

Using the permissions model fully is very complicated because BusinessObjects Enterprise supports cascading, inherited rights on folders and from groups, as well as explicit denials. The most basic permissions (viewing a folder or report),
are resolved transparently within an InfoStore query. Objects that cannot be seen by the user are not returned. However, for more advanced rights, you need to use the
ISecurityInfo.checkCustomRights method.
Listing 30.4 shows how to determine a user's WebI viewing rights.

Listing 30.4. Determining User Permissions

// Webi app rights
IInfoObject app = getWebiAppObj(es, iStore);
if (app != null) {
int[] rightsToCheck = new int[]{
CeWebIntelligenceRightID.INTERACTIVEVIEW,
CeWebIntelligenceRightID.HTMLREPORTPANEL,
CeWebIntelligenceRightID.JAVAREPORTPANEL,
CeWebIntelligenceRightID.DRILLMODE,
CeWebIntelligenceRightID.CREATEDOCUMENTS};
String kind = app.getKind();
String[] kinds = new String[rightsToCheck.length];
for (int i = 0; i < kinds.length; i++)
kinds[i] = kind;
ISecurityInfo secInfo = app.getSecurityInfo();
boolean[] results = secInfo.checkCustomRights(rightsToCheck, kinds, false);
r.setWebiInteractiveViewingAllowed(results[0]);
r.setWebiHtmlReportPanelAllowed(results[1]);
r.setWebiJavaReportPanelAllowed(results[2]);
r.setWebiDrillModeAllowed(results[3]);
r.setWebiCreateDocsAllowed(results[4]);
}

Rights can also be checked individually. Please consult the product documentation for more information.

Setting Custom Properties
The
BusinessObjects Enterprise InfoObject is a very versatile container that easily persists properties for every type of object. The following code shows how you can add custom properties to InfoObjects. Remember the process for updating a document: query for
objects, choose an object, set properties on that object, commit (all) objects.

[View full width]public static void propertiesSet(int objID, String category, HashMap props, IInfoStore


iStore) throws SDKException {
IInfoObjects objs = iStore.query("SELECT * FROM "+category+" WHERE SI_ID="+objID);
IInfoObject obj=(IInfoObject)objs.get(0);
Iterator iter=props.entrySet().iterator();
while (iter.hasNext()){
Object key=(String)iter.next();
obj.properties().setProperty(key,props.get(key));
}
iStore.commit(objs);
}

Note that custom properties cannot be accessed directly using syntax such as
SI_MY_CUSTOM_PROPERTY. To access them you must use the asterix (*) in the SELECT clause when searching for custom properties and then use the
getProperty() method used in the recursive property bag lister.

Using * and Top N

As discussed, queries that return all properties using the asterisk operator (*) might actually return many objects. It is conceivable that a report could have 1,000 schedules associated with it. Selecting the SI_SCHEDINFO project might return
1,000 rows for 1 report alone.
Another must-know tip is how to use Top N. In BusinessObjects Enterprise,
SELECT * returns an upper-limit of 1,000 objects. You can specifically ask for more or fewer objects using
SELECT TOP N. You can see whether you are looking at all of the records that satisfy your query by comparing the
resultInfoObjcts.getResultSize() method to the actual number of records found through the
resultInfoObjcts.size() method.

Query Examples

Now that you understand the syntax of querying the InfoStore, some of the properties, and how they are nested, look at the following examples harvested from the documentation and the author's own BusinessObjects Enterprise projects. The example
includes only the query statement itself and an explanation of what is returned by the query. The InfoStore only returns the objects that the user is permitted to view:

Report templates in the Report Samples folder or subfolders.
SI_ANCESTOR can only be used in the WHERE clause.

SELECT SI_NAME FROM CI_INFOOBJECTS WHERE SI_ANCESTOR=6319 AND SI_INSTANCE=0


List of universe meta-layers.

SELECT * FROM CI_APPOBJECTS WHERE SI_KIND='Universe' ORDER BY SI_NAME ASC


Parent
folder of all universes.

SELECT SI_ID FROM CI_APPOBJECTS WHERE SI_PARENTID=95 AND SI_NAME='Universes'


Scheduled jobs submitted by WRichards for World Sales Report.

[View full width]SELECT SI_ID FROM CI_INFOOBJECTS WHERE SI_NAME = 'World Sales Report' AND SI_SCHEDULEINFO


.SI_SUBMITTER = 'WRichards'

Get recurring scheduled jobs owned by WRichards. SI_RECURRING will be null for nonjobs and 0 for one-time jobs.

SELECT * FROM CI_INFOOBJECTS WHERE SI_OWNERID='WRichards' AND SI_RECURRING=1


Get all scheduled jobs owned by WRichards. Note how selecting
SI_SCHEDINFO forces selection of job objects.

SELECT SI_SCHEDINFO FROM CI_INFOOBJECTS WHERE SI_OWNERID='WRichards'


Get all objects owned by WRichards.

SELECT * FROM CI_INFOOBJECTS WHERE SI_OWNERID='WRichards'


Get report templates owned by WRichards. SI_INSTANCE will return null for nonreport objects, 1 for report instances, and 0 for templates.

SELECT * FROM CI_INFOOBJECTS WHERE SI_OWNERID='WRichards' AND SI_INSTANCE=0


Returns instances of report identified by 215.

SELECT * FROM CI_INFOOBJECTS WHERE SI_PARENTID=215 AND SI_INSTANCE=1


Returns top-level report templates that have been scheduled to run.

SELECT * FROM CI_INFOOBJECTS WHERE SI_RUNNABLE_OBJECT=1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: