In order to get an instance of a certain service, a service manager has to be created. The service manager is the central location where services are instantiated. It comes with a list of all available services registered. If a service is requested the service manager searches its list for a given service, in order to get the assigned factory.
An initial service manager can be created, for example by calling the static method getServiceManager() of the class XComponentContext in the module com.sun.star.comp.helper. The mentioned method bootstraps a servicemanager with the JURT base components registered. The initial component context will be created by calling the method createInitialComponentContext() of the class Bootstrap in the module com.sun.star.comp.helper. Upon application termination you have to explicitly dispose this component context.
XComponentContext xcomponentcontext = com.sun.star.comp.helper.Bootstrap.createInitialComponentContext( null ); XMultiComponentFactory xmulticomponentfactory = xcomponentcontext.getServiceManager();
The service manager implements the class XMultiComponentFactory from the module com.sun.star.lang, that provides methods for creating instances of known services with or without arguments: createInstanceWithContext() and createInstanceWithArgumentsAndContext().
Finally, the service manager is able to create a new instance of the service com.sun.star.comp.urlresolver.UrlResolver. Some services like the UrlResolver service, provide a special XMultiComponentFactory interface which can be used to acquire new services. You can call createInstanceWithContext() of this interface with the service's name as parameter to acquire a service. To create a new UrlResolver object, you would use
Object objectUrlResolver = xmulticomponentfactory.createInstanceWithContext( "com.sun.star.bridge.UnoUrlResolver", xcomponentcontext );
An important, and therefore central, class with the implementation and use of services is the class UnoRuntime. Among other methods, it provides the method queryInterface(), that queries for a new interface to an existing UNO object. The method queryInterface() delegates calls to the implementing objects and is used instead of casts. Thereby, the interface in the programming language Java is more than just an abstract class taken to the extreme, since it allows you to perform a variation on C++s multiple inheritance by creating a class that can be upcast to more than one base type. As opposed to the programming languages Java and C++, the OpenOffice.org Basic UNO binding automatically does all required queries, however, in the Java and C++ language binding, you have to do this manually, which in turn forces you to get your services and interfaces sorted out properly.
In our example, by calling the method queryInterface(), an object of the class type XUnoUrlResolver of the module com.sun.star.bridge will be queried and is able to access the methods of the interface XUnoUrlResolver in contrast to the original object objectUrlResolver.
XUnoUrlResolver xurlresolver = ( XUnoUrlResolver ) UnoRuntime.queryInterface( XUnoUrlResolver.class, objectUrlResolver );
A connection to the remote running office could be established by calling the method resolve with a well specified string parameter. The parameter will be characterized as UNO Uniform Resource Locator. The UNO URL always starts with uno: followed by three parts separated by semicolons. These parts are:
It could be specified as follow:
uno:<connection description>;<protocol description>;<initial object name>
For example, the service manager of the remote running office could be accessed by calling the method resolve(). In order to enable the access, the connection description and the protocol description of the client (Java program) should match with those of the server (remote running OpenOffice.org). Therefore, the office should have been started beforehand with the instruction
<OFFICE_PATH>/program/soffice -accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager.
Object objectInitial = xurlresolver.resolve( "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" );
By calling the method queryInterface(), an object of the class type XMultiComponentFactory of the module com.sun.star.lang will be queried and is able to access the methods of the interface XMultiComponentFactory in contrast to the original object objectInitial.
xmulticomponentfactory = ( XMultiComponentFactory ) UnoRuntime.queryInterface( XMultiComponentFactory.class, objectInitial );
Before creating instances of services in remote, the remote component context is needed. The remote component context from the server can be reveived by using the remote XMultiComponentFactory. The service MultiComponentFactory provides the property DefaultContext.
XPropertySet xpropertysetMultiComponentFactory = ( XPropertySet ) UnoRuntime.queryInterface( XPropertySet.class, xmulticomponentfactory ); Object objectDefaultContext = xpropertysetMultiComponentFactory.getPropertyValue( "DefaultContext" ); xcomponentcontext = ( XComponentContext ) UnoRuntime.queryInterface( XComponentContext.class, objectDefaultContext );
A desktop environment contains tasks with one or more frames in which documents can be loaded. Desktop is the environment for documents which can instantiate within frames. So, before a document could be opened, the service com.sun.star.frame.Desktop should be created.
XComponentLoader xcomponentloader = ( XComponentLoader ) UnoRuntime.queryInterface( XComponentLoader.class, xmulticomponentfactory.createInstanceWithContext( "com.sun.star.frame.Desktop", xcomponentcontext ) );
Now, an empty OpenOffice.org Writer document could be loaded into a new frame by calling the method loadComponentFromURL(). In almost the same manner an empty OpenOffice.org Calc document could be loaded by replacing the URL "private:factory/swriter" with "private:factory/scalc", or "private:factory/sdraw" for OpenOffice.org Draw, or "private:factory/simpress" for OpenOffice.org Impress. If you want to access an existing document of any type known to OpenOffice.org you have to specify an URL like "file:///f:/Test/MyDocument.sxw".
XComponent xcomponent = xcomponentloader.loadComponentFromURL( "private:factory/swriter", "_blank", 0, new PropertyValue[0] );
For better understanding, the complete Java program is listed in the following code. In order to shorten this tutorial the comments are removed, but are available in the source code, that you could download from http://api.openoffice.org/source/browse/api/odk/examples/java/DocumentConverter.
import com.sun.star.bridge.XUnoUrlResolver; import com.sun.star.lang.XComponent; import com.sun.star.lang.XMultiComponentFactory; import com.sun.star.uno.XComponentContext; import com.sun.star.uno.UnoRuntime; import com.sun.star.frame.XComponentLoader; import com.sun.star.beans.PropertyValue; import com.sun.star.beans.XPropertySet;
public class DocumentLoader { public static void main(String args[]) { try { XComponentContext xcomponentcontext = com.sun.star.comp.helper.Bootstrap.createInitialComponentContext( null ); XMultiComponentFactory xmulticomponentfactory = xcomponentcontext.getServiceManager(); Object objectUrlResolver = xmulticomponentfactory.createInstanceWithContext( "com.sun.star.bridge.UnoUrlResolver", xcomponentcontext ); XUnoUrlResolver xurlresolver = ( XUnoUrlResolver ) UnoRuntime.queryInterface( XUnoUrlResolver.class, objectUrlResolver ); Object objectInitial = xurlresolver.resolve( args[ 0 ] ); xmulticomponentfactory = ( XMultiComponentFactory ) UnoRuntime.queryInterface( XMultiComponentFactory.class, objectInitial ); XPropertySet xpropertysetMultiComponentFactory = ( XPropertySet ) UnoRuntime.queryInterface( XPropertySet.class, xmulticomponentfactory ); Object objectDefaultContext = xpropertysetMultiComponentFactory.getPropertyValue( "DefaultContext" ); xcomponentcontext = ( XComponentContext ) UnoRuntime.queryInterface( XComponentContext.class, objectDefaultContext ); XComponentLoader xcomponentloader = ( XComponentLoader ) UnoRuntime.queryInterface( XComponentLoader.class, xmulticomponentfactory.createInstanceWithContext( "com.sun.star.frame.Desktop", xcomponentcontext ) ); XComponent xcomponent = xcomponentloader.loadComponentFromURL( args[ 1 ], "_blank", 0, new PropertyValue[0] ); System.exit(0); } catch( Exception exception ) { System.err.println( exception ); } } }