Querying the InfoStore
2013-10-18 10:45
323 查看
Querying the InfoStore
Formost 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 asFolder, 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
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(); } |
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 |
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"; } } |
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]); } |
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 return1,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 exampleincludes 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
相关文章推荐
- Building GDB for Darwin
- Java: Queue
- Java GUI编程SwingUtilities.invokeLater作用
- Fluentd+ElasticSearch+Kibana 搭建日誌類文件分析器 配置篇
- iOS7图标模板和UI工具包汇总
- (三)UITabBar and UINavigationController基础教程之UITableView的插入删除移动
- ORA-02429: cannot drop index used for enforcement of unique/primary key
- Number Sequence
- iOS手势UIGestureRecognizer整理
- C# NameValueCollection集合 .
- MyGui笔记(4)渲染过程
- MyGui笔记(3)控件对齐方式和所在层
- UIKit Dynamics Tutorial
- 给UIAlertView UIActionSheet 添加block支持
- Essential iOS 7 Developer’s Guide
- IOS UILabel
- easyUI自定义validatebox.
- UITextField用法小结
- UIColor,CGColor,CIColor三者的区别和联系
- EasyUI datagrid不能绑定数据问题,要注意返回模型中不能包含DataTime格式数据