UNO-IDL types introspection in Java


Tue 27 June 2006 By nuxeo

Since the beginning of the Google Summer of Code 2005 when I started the
OpenOffice.org Eclipse Integration project, I wanted to provide a code
completion feature for UNO-IDL. At the beginning I thought at a huge
mecanism using IDL parsers to fetch the informations. However, I investigate
a bit more on Juergen and Laurent ideas: using the UNO reflection API to
introspect any type.




After a small test, I could manage to do it in a small Java application.
I'll try to explain what I did. All the code provided is in very simple Java
main and should be launched with a correct ClassPath (the OpenOffice.org
jars) and LD_LIBRARY_PATH set to your OpenOffice.org program directory. This
is because OOo Jars use the OOo shared libraries.


First thing to do is to bootstrap OpenOffice.org to get a component
context. There is no mystery in this code: using the Bootstrap class and one
of its method is the best way to do it.



try {

//*

// 1- Bootstrap of OpenOffice.org

//*

String sofficepath = "file:///opt/openoffice.org2.0/program";

String unoini = sofficepath + "/unorc"; // To change in uno.ini for Windows



Hashtable params = new Hashtable();

params.put("SYSBINDIR", sofficepath);



XComponentContext xCtx = Bootstrap.defaultBootstrap_InitialComponentContext(

unoini, params);

System.out.println(">>> OOo has been bootstrapped");


This second part of code loads a types registry external to
OpenOffice.org. You will have to load some if you want to introspect in
addons or components types (I mean types which aren't defined in the
OpenOffice.org API)



//*

// 2- Opening a local types regitry

//*



String localRegistry = "file:///path/to/your/types.rdb";



XMultiComponentFactory xMCF = xCtx.getServiceManager();

XSimpleRegistry xReg = (XSimpleRegistry)UnoRuntime.queryInterface(

XSimpleRegistry.class,

xMCF.createInstanceWithContext("com.sun.star.registry.SimpleRegistry",

xCtx));



xReg.open(localRegistry, true, false);

System.out.println(">>> Local Registry opened");


The thirsd part is the interesting one for this blog article. The first
thing to do before introspecting, is to create a
com.sun.star.reflection.CoreReflection service. This one will provide two
simple methods:



  • forName(): gets a type definition from a string representing the type
    name (dot-separated, eg: com.sun.star.uno.XInterface)

  • getType(): gets a type definition from an any UNO object.


In our case, we imagine that we don't have any running object to
introspect, but we have just its name (remain that is for code completion
purpose), thus we will use the forName() method (see point 3.1 in the
code).


When we have the desired XIdlClass, we can do what we like with: asking
its name, its methods or attributes and so on. To get more help on this
please report to the
com.sun.star.reflection.XIdlClass API
.



//*

// 3- Getting the methods of XInterface

//*



// 3.1 - Creating a CoreReflection service

Object oReflection = xCtx.getServiceManager().createInstanceWithContext(

"com.sun.star.reflection.CoreReflection", xCtx);

XIdlReflection xReflection = (XIdlReflection)UnoRuntime.queryInterface(

XIdlReflection.class, oReflection);



System.out.println(">>> Reflection service fetched");



//
3.2 - Using XIdlReflexion.forName() like Class.forName() in Java

XIdlClass xClazz = xReflection.forName("com.sun.star.uno.XInterface");

if (xClazz != null) {

System.out.println(">>> IdlClass found: " + xClazz.getName());



// Check for it's methods

System.out.println(">>> Methods:");



//** 3.3 - A simple use of XIdlClass to list the methods

XIdlMethod[] methods = xClazz.getMethods();

for (int i=0; i<methods.length; i++) {

System.out.println(" * " + methods[i].getName());

}



} else {

System.out.println(">>> No IdlClass found");

}


The rest is the normal ending of a try-catch block and is provided only
for the reader to copy-paste the code.



} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}



System.exit(0);


So you can imagine that I will now have a lot of work to integrate this
in the plugin, but you will have it in an indetermined delay... depending on
my time.


(Post originally written by Cedric Bosdonnat on the old Nuxeo blogs.)


Category: Product & Development