Special Service Manager Configurations

From Apache OpenOffice Wiki
Jump to: navigation, search



The com.sun.star.container.XSet interface allows the insertion or removal of com.sun.star.lang.XSingleServiceFactory or com.sun.star.lang.XSingleComponentFactory implementations into or from the service manager at runtime without making these changes persistent. When the office applications terminate, all the changes are lost. The inserted object must support the com.sun.star.lang.XServiceInfo interface. This interface returns the same information as the XServiceInfo interface of the component implementation which is created by the component factory.

With this feature, a running office can be connected, a new factory inserted into the service manager and the new service instantiated without registering it beforehand. This method of hard coding the registered services is not acceptable with Apache OpenOffice, because it must be extended after compilation.

Java applications can use a native persistent service manager in their own process using JNI (see Java Language Binding), or in a remote process. But note, that all services will be instantiated in this remote process.

Dynamically Modifying the Service Manager

Bootstrapping in pure Java is simple, by calling the static runtime method createInitialComponentContext() from the Bootstrap class. The following small test program shows how to insert service factories into the service manager at runtime. The sample uses the Java component from the section Simple Component in Java. The complete code can be found with the JavaComp sample component.

The example shows that there is the possibility to control through command line parameter, whether the service is inserted in the local Java service manager or the remote office service manager. If it is inserted into the office service manager, access the service through Apache OpenOffice Basic. In both cases, the component runs in the local Java process.

If the service is inserted into the office service manager, instantiate the component through Apache OpenOffice Basic calling createUnoService("JavaTestComponentB"), as long as the Java process is not terminated. Note, to add the new types to the office process by one of the above explained mechanisms, use uno.ini.

  public static void insertIntoServiceManager(
              XMultiComponentFactory serviceManager, Object singleFactory)
          throws com.sun.star.uno.Exception {
      XSet set = (XSet ) UnoRuntime.queryInterface(XSet.class, serviceManager);
      set.insert(singleFactory);
  }
  
  public static void removeFromServiceManager(
              XMultiComponentFactory serviceManager, Object singleFactory)
          throws com.sun.star.uno.Exception {
      XSet set = (XSet) UnoRuntime.queryInterface( XSet.class, serviceManager);
      set.remove(singleFactory);
    
  }
  
  public static void main(String[] args) throws java.lang.Exception {
      if (args.length != 1) {
          System.out.println("usage: RunComponent local|uno-url");
          System.exit(1);
      }
      XComponentContext xLocalComponentContext =
          Bootstrap.createInitialComponentContext(null);
    
      // initial serviceManager
      XMultiComponentFactory xLocalServiceManager = xLocalComponentContext.getServiceManager();
        
      XMultiComponentFactory xUsedServiceManager = null;
      XComponentContext xUsedComponentContext = null;
      if (args[0].equals("local")) {
          xUsedServiceManager = xLocalServiceManager;
          xUsedComponentContext = xLocalComponentContext;
  
          System.out.println("Using local servicemanager");
          // now the local servicemanager is used !
      }
      else {
          // otherwise interpret the string as uno-url
          Object xUrlResolver = xLocalServiceManager.createInstanceWithContext(
              "com.sun.star.bridge.UnoUrlResolver", xLocalComponentContext);
          XUnoUrlResolver urlResolver = (XUnoUrlResolver) UnoRuntime.queryInterface(
              XUnoUrlResolver.class, xUrlResolver);
          Object initialObject = urlResolver.resolve(args[0]);
          xUsedServiceManager = (XmultiComponentFactory) UnoRuntime.queryInterface(
              XMultiComponentFactory.class, initialObject);
  
          System.out.println("Using remote servicemanager");
          // now the remote servicemanager is used. 
      }
  
      // retrieve the factory for the component implementation
      Object factory = TestServiceProvider.__getServiceFactory(
          "componentsamples.TestComponentB", null, null);
  
      // insert the factory into the servicemanager
      // from now on, the service can be instantiated !
      insertIntoServiceManager( xUsedServiceManager, factory );
    
      // Now instantiate one of the services via the servicemanager !
      Object objTest= xUsedServiceManager.createInstanceWithContext(
          "JavaTestComponentB",xUsedComponentContext);
    
      // query for the service interface
      XSomethingB xs= (XSomethingB) UnoRuntime.queryInterface(
          XSomethingB.class, objTest);
    
      // and call the test method.
      String s= xs.methodOne("Hello World");
      System.out.println(s);
      
      // wait until return is pressed 
      System.out.println( "Press return to terminate" );
      while (System.in.read() != 10);
    
    // remove it again from the servicemanager, otherwise we have
    // a dangling reference ( in case we use the remote service manager )
    removeFromServiceManager( xUsedServiceManager, factory );
  
      // quit, even when a remote bridge is running
      System.exit(0);
  }

Creating a ServiceManager from a Given Registry File

To create a service manager from a given registry, use a single registry that contains the type library and component registration information. Hard code the name of the registry in the program and use the createRegistryServiceFactory() function located in the cppuhelper library.

  #include <cppuhelper/servicefactory.hxx>
  
  using namespace com::sun::star::uno;
  using namespace com::sun::star::lang;
  using namespace rtl;
  using namespace cppu;
  int main( )
  {
      // create the service manager on the registry test.rdb
      Reference< XMultiServiceFactory > rServiceManager = 
                  createRegistryServiceFactory( OUString::createFromAscii( "test.rdb" ) );
  
      // instantiate a sample service with the service manager.
      Reference< XInterface > rInstance =
                  rServiceManger->createInstance( 
                  OUString::createFromAscii("com.sun.star.bridge.UnoUrlResolver" ) );
  
      // continue to connect to the office ....
  }
Documentation note.png This instantiates the old style service manager without the possibility of offering a component context. In future versions you will be able to use the new service manager here.
Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages