obj extensions to java cesdk ideas on fine-grained persistence perspectives for bip thierry bravier...
TRANSCRIPT
obj extensions to Java CeSdk ideas on fine-grained persistence
perspectives for BIP
obj extensions to Java CeSdk ideas on fine-grained persistence
perspectives for BIP
Thierry BravierVersion 1.0
6 March 2007
Slide 2
CeSdk is very flexible and functional as it is
but requires some level of expertise to use correctly
Idea: develop a strongly typed layer over CeSdk to fully benefit from modern languages C++/Java5/.NET2&3 This presentation focuses on Java5 extensions for Java CeSdk Similar work has already been developed for C++ over wire objects
Session
Desktop plugins
Collection of info-objects
Info-object and bag
Query syntax
Copyright © 2007 Business Objects S.A. All rights reserved.
CeSdk + obj: where we are, where we could go
Slide 3
The several techniques used aim at ensuring …
Strong typing C++ templates / Java 5 generics / .NET 2+ generics Statically type everything that can be
• Typed properties that « know » their type• Typed (reified) plugins that « know » their info object type and more• Typed Query syntax API (forget about string concatenation)• Ban casts
Const correctness• By design in C++• Covariant return type in Java 5• To be explored in .NET
ie. Favor non mutable over mutable• IKSession, IKObjs, IKObj, IKProperty …• Would you want a pure consumer to unwillingly modify objects?
Copyright © 2007 Business Objects S.A. All rights reserved.
CeSdk + obj: techniques used (1/2)
Slide 4
The several techniques used aim at ensuring …
Extensibility Combine predefined property types into user defined ones An IObj isAn Ibag
• So a typed property working on bags can work on objs (code re-use)
Copyright © 2007 Business Objects S.A. All rights reserved.
CeSdk + obj: techniques used (2/2)
Slide 5 Copyright © 2007 Business Objects S.A. All rights reserved.
Session management can be complex To ease session life-cycle ISession is a Closeable
• close (alternatively release) must be called to release acquired resource• Currently only building session with a Logon object (session must be logged off),
but this can be generalized for tokens or serialized form
IKSession can only query const objects collections
ISession can query mutable objects collections
CeSdk + obj: ISession (1/1)
final ISession session = ISession.logon // Logon non-mutable object .userName("tbravier") // Administrator .password("sesame") // blank .authentication("secEnterprise") // secEnterprise .cmsName("tbravier-titan") // localhost .session(); // logs onsession.close();
Slide 6 Copyright © 2007 Business Objects S.A. All rights reserved.
Today, a plugin is represented by its SI_KIND string But a plugin should know its Java associated type
• A plugin can be used as a factory to extend a collection in a type-safe way• A plugin can be useful to restrict a query result set
CeSdk + obj: IObjPlugin Desktop plugins (1/2)
final IInfoObj<IFolder> folderObj = session.create(IInfoObjPlugin.FOLDER // knows about IFolder .spec(parentSid) // make sure new object has a parent .name("NewFolderName”) // optionaly specify name );
Query.select .prop(SpecialProp.STAR) .from(Ci.APPOBJECTS) .where(IInfoObjPlugin.FOLDER); // here plugin is used as a predicate
Slide 7 Copyright © 2007 Business Objects S.A. All rights reserved.
A plugin is a kind of metaclass hierarchies of plugin classes are possible A plugin can be used as a type token like Java5 classes
CeSdk + obj: IObjPlugin Desktop plugins (2/2)
// typed Java5 class literalClass<String> cls = String.class;
// typed plugin literalIObjPlugin<IPersonObj> plg = IPersonObj.plugin;
void test(String data, IPersonObj obj) { assert(data.getClass() == String.class); assert(obj.plugin() == IPersonObj.plugin);}
Slide 8
The several techniques used aim at ensuring …
Strong typing C++ templates / Java 5 generics / .NET 2+ generics Statically type everything that can be
• Typed properties that « know » their type• Typed (reified) plugins that « know » their info object type and more• Ban casts
Const correctness ie. Favor non mutable over mutable
• IKSession, IKObjs, IKObj, IKProperty …• Would you want a pure consumer to unwillingly modify objects?
By design in C++ Covariant return type in Java 5 To be explored in .NET
Copyright © 2007 Business Objects S.A. All rights reserved.
CeSdk + obj: techniques used (1/2)
Slide 9 Copyright © 2007 Business Objects S.A. All rights reserved.
CeSdk + obj: IObjs Collection (1/2)
An IObjs is iterable (type-safe) and indexed by sids
A collection of mutable objects may commit IObjs is a Flushable whose flush (alt. commit) updates CMS
An IObjs « knows » its ISession incremental loading, finding target objects of relations …
Objects are created / destroyed inside collections Simplification: ISession owns IObjs which owns each IObj
iobjs.create(IPersonObj.plugin.spec(IPersonObj.defaultFolderId));iobjs.commit();
iobjs.destroy(personObj);iobjs.commit();
final IPersonObj personObj = iobjs.create(IPersonObj.plugin .spec(IPersonObj.defaultFolderId));personObj.commit(); // shortcutpersonObj.destroy().commit(); // shortcut
Slide 10 Copyright © 2007 Business Objects S.A. All rights reserved.
An IKObjs is iterable (type-safe) and indexed by sids
An IKObjs collection only contains IKObj’s but can grow
An IKObjs « knows » its IKSession
CeSdk + obj: IObjs Collection (2/2)
for (final IUser user : ksession.objs( "select static from ci_systemobjects where si_kind = 'User'") .infos(IInfoObjPlugin.USER)) { testUser(user);}
Slide 11
How to create objects Don’t forget to set
• SI_PARENTID or SI_PARENT_CUID• SI_KIND (see slide on plugins)• SI_NAME (optionaly)
How to manage properties in a type-safe way• Property name (and associated integer value)• Type• Value• Bags
Predefined property types• boolean SiBool Boolean• int SiInt4 Integer• long SiInt8 Long• double SiFlt8 Double• String SiStrg String• Date SiTime Date
Copyright © 2007 Business Objects S.A. All rights reserved.
CeSdk + obj: IObj & IBag object and bag (1/4)
Slide 12
How to separate authoring & consumption when consuming missing data often means something’s wrong when authoring missing data should be inserted
How to traverse relationships relationships targets really are info objects, not sids this asks for « connected » objects that know their collection
How to access missing objects To get missing objects
• an additional query (with a merge) is needed• the session is needed
This is important for• Authoring: adding/removing objects graphs to/from edition workspace• Consumption: incremental loading depending on previous query results
Copyright © 2007 Business Objects S.A. All rights reserved.
CeSdk + obj: IObj & IBag object and bag (2/4)
Slide 13
How to simply deal with default values, null values
How to manage values properties for user-defined types Enumerated types (encoded as string, cf. SiRainbow in demo) Struct (Bag + field, cf. SiAnimal in demo) Encoding (cf. Locale …)
How to manage relations properties encoding as bags 3 kinds of relations
• Single SiSRel Integer• Unordered SiURel Set<Integer>• Ordered SiORel List<Integer>
Copyright © 2007 Business Objects S.A. All rights reserved.
CeSdk + obj: IObj & IBag object and bag (3/4)
Slide 14 Copyright © 2007 Business Objects S.A. All rights reserved.
Using predefined value and relation properties
CeSdk + obj: IObj & IBag object and bag (4/4)
final SiSub SI_BAG = SiSub.make("SI_BAG");final SiBool SI_BOOL = SiBool.make("SI_BOOL");final SiInt4 SI_INT4 = SiInt4.make("SI_INT4");final SiInt8 SI_INT8 = SiInt8.make("SI_INT8");final SiFlt8 SI_FLT8 = SiFlt8.make("SI_FLT8");final SiTime SI_TIME = SiTime.make("SI_TIME");final SiStrg SI_STRG = SiStrg.make("SI_STRG");
final SiSrel SI_SREL = SiSrel.make("SI_SREL");final SiUrel SI_UREL = SiUrel.make("SI_UREL");final SiOrel SI_OREL = SiOrel.make("SI_OREL");
final double flt8 = obj.set(SI_BAG).set(SI_BAG).set(SI_FLT8);final String strg = obj.set(SI_BAG).set(SI_BAG).set(SI_STRG);final Date time = obj.set(SI_BAG).set(SI_BAG).set(SI_TIME);
final int int4 = obj.get(SI_BAG).get(SI_BAG).get(SI_INT4);obj.set(SI_BAG).set(SI_BAG).set(SI_INT4, int4 + 1);
final Integer si_srel = obj.get(SI_SREL);
Slide 15 Copyright © 2007 Business Objects S.A. All rights reserved.
let’s take a look !
Slide 16 Copyright © 2007 Business Objects S.A. All rights reserved.
CeSdk + obj: typed properties (1/2)
values
Slide 17 Copyright © 2007 Business Objects S.A. All rights reserved.
CeSdk + obj: typed properties (2/2)
relations
Slide 18 Copyright © 2007 Business Objects S.A. All rights reserved.
Queries are immutable Libraries of useful query contants can be written
Forget about escaping, precedences and string concat
Value properties become predicates
Relation constants (not detailed) become predicates
Plugins become predicates
CeSdk + obj: Query syntax (1/2)
Query.select .top(5) .prop(SI_NAME, SI_DESCRIPTION, SI_FULLNAME) .from(Query.Ci.SYSTEMOBJECTS) .where(IInfoObjPlugin.USER .or(SI_ID.eq(95))) ;
Slide 19 Copyright © 2007 Business Objects S.A. All rights reserved.
Using relation traversal predicates (descendents …)
CeSdk + obj: Query syntax (2/2)
Query.select .top(5) .prop(SI_NAME, SI_DESCRIPTION, SI_CUID, SI_UPDATE_TS, SI_KIND) .from(Query.Ci.APPOBJECTS) .where(IPersonObj.plugin // ie. SI_KIND.eq("TB_Person") .and(FOLDER_HIERARCHY.descendents(SI_ID.eq(95))) .and(SI_NAME.in("John", "O'Brien"))) ;
Slide 20
obj and mes code dependency graph
Copyright © 2007 Business Objects S.A. All rights reserved.
obj package extends CeSdk• Strongly typed• Generics
persistence exposes• Metadata (cf. xsd+) in plugins objects• Inversion of control (ioc)
• Plugins register into the application• Application loads plugins
meta = persistence + obj• Fine-grained authoring &
consumption algorithms
Slide 21 Copyright © 2007 Business Objects S.A. All rights reserved.
obj and mes code metrics
MES packages in lines of code (loc)
Total size of code = 22 kloc
mes3852% persistence
455523%
plugin7384%
meta732637%
obj669434%
mes
persistence
plugin
meta
obj
Slide 22
obj + persistence = meta UML design
Copyright © 2007 Business Objects S.A. All rights reserved.
service
service
«interface»IEditionContext
«interface»IRetrievalContext
«interface»plugin::IServiceContext
«interface»IElem
+persistentId() : string
«interface»IIdElem
+folderId() : string
«interface»ITopElem
+editor()+retriever()
«interface»IElemPlugin
«interface»IIdElemPlugin
«interface»ITopElemPlugin
«metaclass»plugin
«metaclass»plugin
«metaclass»plugin
+commit()
«interface»IEditionManager
+retrieve(in cuid : string)
«interface»IRetrievalManager
«interface»IDeployableManager
+create()+setElemField()+destroy()
«interface»IEditor
+getElemField()
«interface»IRetriever
«interface»plugin::IService
service
+deploy(in topModelPlugin : ITopElemPlugin)+deploy(in topModelClass)
«interface»plugin::IDeployable
+service(in modelClass)
«interface»plugin::IManager
context
context
context
kelems
«interface»IElems
«interface»IKElems
elems
«interface»meta::IMetaObj
«interface»meta::IIdMetaObj
«interface»meta::ITopMetaObj
«interface»meta::IMetaObjPlugin
«interface»meta::IIdMetaObjPlugin
«interface»meta::ITopMetaObjPlugin
«metaclass»plugin
«metaclass»plugin
«metaclass»plugin
«interface»obj::IBag
«interface»obj::IObj
«interface»obj::IObjPlugin
«metaclass»plugin
«interface»obj::IObjs
«interface»obj::ISession
«interface»meta::IMetaObjs