SAO - Service As Object

An enhancement to the Java API, that allows you to access Services as Objects. This greatly simplifies the writing of Java code for OOo.
SF page : : download
Admin : Jonathon Love
License : GNU Lesser General Public License (LGPL)


Communication with (OOo) is done through Universal Network Objects (UNO). The OOo SDK provides access to these objects through interfaces, these interfaces are acquired via the UnoRuntime.
If you've done much programming with OOo and UNO, the following will be quite familiar.

Object tmp = classLoader.loadComponentFromURL("private:factory/scalc","_blank",0,new PropertyValue[]{});
XSpreadsheetDocument sd = (XSpreadsheetDocument)
UnoRuntime.queryInterface(XSpreadsheetDocument.class, tmp);
tmp = sd.getSheets();
XIndexAccess ia = (XIndexAccess)
UnoRuntime.queryInterface(XIndexAccess.class, tmp);
tmp = ia.getByIndex(0);
XSpreadsheet s = (XSpreadsheet)
UnoRuntime.queryInterface(XSpreadsheet.class, tmp);
XCell c = s.getCellByPosition(0,0);
XPropertySet ps = (XPropertySet)
UnoRuntime.queryInterface(XPropertySet.class, c);
ps.setPropertyValue("CellBackColor", new Integer(0xFF0000));

I personally find that painful to look at, and incredibly tedious to code.
Hence the writing of SAO. A SAO object takes a single argument in its constructor, the argument must be an interface to a service, and that service must correspond to the SAO object being constructed.

For example:
the XSpreadsheet above called 's' could be used to create a SAO object. We know that the XSpreadsheet interface is being supplied by the Spreadsheet service, so we choose the SAO object of the same name;

Spreadsheet saoSpreadsheet = new Spreadsheet(s);

objects of the SAO class Spreadsheet implement all the non-optional interfaces of the service Spreadsheet. so we can go:


Hence, we could rewrite the above code example:

Object tmp = classLoader.loadComponentFromURL("private:factory/scalc","_blank",0,new PropertyValue[]{});
SpreadsheetDocument sd = new SpreadsheetDocument(tmp);
Spreadsheets ss = new Spreadsheets(sd.getSheets());
Spreadsheet s = new Spreadsheet(ss.getByIndex(0));
Cell c = new Cell(s.getCellByPosition(0, 0));
c.setPropertyValue("CellBackColor", new Integer(0xFF0000));

To my mind, this is far simpler, and easier to read.

If the object passed into the constructor isn't an interface to a service which supports all the interfaces that the sao object supports, a ClassCastException will be thrown when an unsupported method is called.

Optional Interfaces.
The SAO object does not implement the Optional Interfaces. If you know a particular service supports an Optional Interface(s), you can create a SAO object that also supports it. For example, if you had an interface to an OfficeDocument, which you knew implemented the optional interface XEventBroadcaster, you could go:

moo = new OfficeDocument.EventBroadcaster(in);

The class OfficeDocument.EventBroadcaster extends OfficeDocument and implements XEventBroadcaster.

If the service also implements the optional interface XEventsSupplier, you can go:

moo = new OfficeDocument.EventBroadcaster.EventsSupplier(in);

Just drop the X off the front of the interface name, and chain them along after the saoObject name with dots between them. They need to be in order though.

This depends on the OOo .jar files in the -OfficePath-/program/classes directory, so make sure you have them in your classpath. It's built for OOo 1.1, but ithink it's prolly still work for OOo 1.0. Lemme know your experiences.
There are a couple of obscure files missing, I doubt anyone but power users (who probably won't use this anyway) will miss them though. If you find any bugs let me know.

Jonathon : aprendiz at cbl dot com dot au

Future versions, I'm wanting to add, say for getSheets(), getSheetsAsObject() which has a return type of Spreadsheets. This will allow you to, for the above program

Object tmp = classLoader.loadComponentFromURL("private:factory/scalc","_blank",0,new PropertyValue[]{});
SpreadsheetDocument sd = new SpreadsheetDocument(tmp);
Spreadsheet s = sd.getSheetsAsObject().getByIndexAsObject(0);
Cell c = s.getCellByPositionAsObject(0,0);
c.setPropertyValue("CellBackColor", new Integer(0xFF0000));

Simpler Again Logo