Difference between revisions of "Documentation/DevGuide/WritingUNO/Possible Structures for Java Components"

From Apache OpenOffice Wiki
Jump to: navigation, search
m
m (FINAL VERSION FOR L10N)
Line 5: Line 5:
 
|NextPage=Documentation/DevGuide/WritingUNO/Running and Debugging Java Components
 
|NextPage=Documentation/DevGuide/WritingUNO/Running and Debugging Java Components
 
}}
 
}}
[[zh:Zh/Documentation/DevGuide/WritingUNO/Possible Structures for Java Components]]
+
{{Documentation/DevGuideLanguages|Documentation/DevGuide/WritingUNO/{{SUBPAGENAME}}}}
 
{{DISPLAYTITLE:Possible Structures for Java Components}}
 
{{DISPLAYTITLE:Possible Structures for Java Components}}
 
__NOTOC__
 
__NOTOC__

Revision as of 08:51, 13 May 2009



The implementation of a component depends on the needs of the implementer. The following examples show some possible ways to assemble a component. There can be one implemented object or several implemented objects per component file.

One Implementation per Component File

There are additional options if implementing one service per component file:

  • Use a flat structure with the static component operations added to the service implementation class directly.
  • Reserve the class with the implementation name for the static component operation and use an inner class to implement the service.

Implementation Class with Component Operations

An implementation class contains the static component operations. The following sample implements an interface com.sun.star.test.XSomething in an implementation class JavaComp.TestComponent:

  // UNOIDL: interface example specification
  module com { module sun { module star { module test { 
 
  interface XSomething: com::sun::star::uno::XInterface
  { 
      string methodOne([in]string val);
  }; 
  }; }; }; };

A component that implements only one service supporting XSomething can be assembled in one class as follows:

  package JavaComp;
 
  ...
 
  public class TestComponent implements XSomething, XTypeProvider, XServiceInfo {
 
      public static final String __serviceName="com.sun.star.test.JavaTestComponent"; 
 
      public static XSingleServiceFactory __getServiceFactory(String implName,
                                XMultiServiceFactory multiFactory, XRegistryKey regKey) {
      XSingleServiceFactory xSingleServiceFactory = null;
 
      if (implName.equals( TestComponent.class.getName()) )
          xSingleServiceFactory = FactoryHelper.getServiceFactory( TestComponent.class,
                                TestComponent.__serviceName, multiFactory, regKey); 
          return xSingleServiceFactory;
      }
 
      public static boolean __writeRegistryServiceInfo(XRegistryKey regKey){
          return FactoryHelper.writeRegistryServiceInfo( TestComponent.class.getName(),
                      TestComponent.__serviceName, regKey);
      }
 
      // XSomething
      string methodOne(String val) {
          return val;
      }
      //XTypeProvider
      public com.sun.star.uno.Type[] getTypes( ) {
          ...
      } 
      // XTypeProvider
      public byte[] getImplementationId( ) {
          ...
      }
      //XServiceInfo
      public String getImplementationName( ) {
          ...
      }
      // XServiceInfo
      public boolean supportsService( /*IN*/String serviceName ) {
          ...
      }
      //XServiceInfo
      public String[] getSupportedServiceNames( ) {
          ...
      } 
  }

The class implements the XSomething interface. The IDL description and documentation provides information about its functionality. The class also contains the functions for factory creation and registration, therefore the manifest entry must read as follows:

 RegistrationClassName: JavaComp.TestComponent

Implementation Class with Component Operations and Inner Implementation Class

To implement the component as inner class of the one that provides the service factory through __getServiceFactory(), it must be a static inner class, otherwise the factory provided by the FactoryHelper cannot create the component. An example for an inner implementation class is located in the sample com.sun.star.comp.demo.DemoComponent.java provided with the SDK. The implementation of __getServiceFactory() and __writeRegistryServiceInfo() is omitted here, because they act the same as in the implementation class with component operations above.

  package com.sun.star.comp.demo;
 
  public class DemoComponent {
 
      ...
      // static inner class implements service com.sun.star.demo.DemoComponent
      static public class _Implementation implements XTypeProvider, 
                      XServiceInfo, XInitialization, XWindowListener, 
                      XActionListener, XTopWindowListener {
 
      static private final String __serviceName = "com.sun.star.demo.DemoComponent";
      private XMultiServiceFactory _xMultiServiceFactory;
 
      // Constructor
      public _Implementation(XMultiServiceFactory xMultiServiceFactory) {
      }
  }
 
  // static method to get a single factory creating the given service from the factory helper
  public static XSingleServiceFactory __getServiceFactory(String implName,
                                          XMultiServiceFactory multiFactory, 
                                          XRegistryKey regKey) {
              ...
      }
 
      // static method to write the service information into the given registry key
      public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) {
          ...
      }
 
  }

The manifest entry for this implementation structure again has to point to the class with the static component operations:

 RegistrationClassName: com.sun.star.comp.demo.DemoComponent

Multiple Implementations per Component File

To assemble several service implementations in one component file, implement each service in its own class and add a separate class containing the static component operations. The following code sample features two services: TestComponentA and TestComponentB implementing the interfaces XSomethingA and XSomethingB with a separate static class TestServiceProvider containing the component operations.

The following are the UNOIDL specifications for XSomethingA and XSomethingB:

  module com { module sun { module star { module test {
  interface XSomethingA: com::sun::star::uno::XInterface
  { 
      string methodOne([in]string value);
  }; 
  }; }; }; }; 
 
  module com { module sun { module star { module test {
  interface XSomethingB: com::sun::star::uno::XInterface
  { 
      string methodTwo([in]string value);
  }; 
  }; }; }; };

TestComponentA implements XSomethingA:

  package JavaComp;
 
  public class TestComponentA implements XTypeProvider, XServiceInfo, XSomethingA {
      static final String __serviceName= "JavaTestComponentA"; 
 
      static byte[] _implementationId;
 
      public TestComponentA() {
      }
 
      // XSomethingA
      public String methodOne(String val) {
          return val;
      }
 
      //XTypeProvider
      public com.sun.star.uno.Type[] getTypes( ) {
          Type[] retValue= new Type[3];
          retValue[0]= new Type( XServiceInfo.class);
          retValue[1]= new Type( XTypeProvider.class);
          retValue[2]= new Type( XSomethingA.class);
          return retValue;
      }
 
      //XTypeProvider
      synchronized public byte[] getImplementationId( ) {
          if (_implementationId == null) {
              _implementationId= new byte[16];
              int hash = hashCode();
              _implementationId[0] = (byte)(hash & 0xff);
              _implementationId[1] = (byte)((hash >>> 8) & 0xff);
              _implementationId[2] = (byte)((hash >>> 16) & 0xff);
              _implementationId[3] = (byte)((hash >>>24) & 0xff);
          }
          return _implementationId;
      }
 
      //XServiceInfo
      public String getImplementationName( ) {
          return getClass().getName();
      }
      // XServiceInfo
      public boolean supportsService( /*IN*/String serviceName ) {
      if ( serviceName.equals( __serviceName)) 
              return true;
          return false;
      }
 
      //XServiceInfo
      public String[] getSupportedServiceNames( ) {
          String[] retValue= new String[0];
          retValue[0]= __serviceName;
          return retValue;
      }
  }

TestComponentB implements XSomethingB. Note that it receives the component context and initialization arguments in its constructor.

  package JavaComp;
 
  public class TestComponentB implements XTypeProvider, XServiceInfo, XSomethingB {
      static final String __serviceName= "JavaTestComponentB"; 
 
      static byte[] _implementationId;
      private XComponentContext context; 
      private Object[] args; 
 
      public TestComponentB(XComponentContext context, Object[] args) {
          this.context= context; 
          this.args= args;
      }
 
      // XSomethingB
      public String methodTwo(String val) {
          if (args.length > 0 && args[0] instanceof String )
          return (String) args[0];
          return val;
      }
 
      //XTypeProvider
      public com.sun.star.uno.Type[] getTypes( ) {
          Type[] retValue= new Type[3];
          retValue[0]= new Type( XServiceInfo.class);
          retValue[1]= new Type( XTypeProvider.class);
          retValue[2]= new Type( XSomethingB.class);
          return retValue;
      }
 
      //XTypeProvider
      synchronized public byte[] getImplementationId( ) {
          if (_implementationId == null) {
              _implementationId= new byte[16];
              int hash = hashCode();
              _implementationId[0] = (byte)(hash & 0xff);
              _implementationId[1] = (byte)((hash >>> 8) & 0xff);
              _implementationId[2] = (byte)((hash >>> 16) & 0xff);
              _implementationId[3] = (byte)((hash >>>24) & 0xff);
          }
          return _implementationId;
      }
 
      //XServiceInfo
      public String getImplementationName( ) {
          return getClass().getName();
      }
 
      // XServiceInfo
      public boolean supportsService( /*IN*/String serviceName ) {
          if ( serviceName.equals( __serviceName)) 
              return true;
              return false;
      }
 
      //XServiceInfo
      public String[] getSupportedServiceNames( ) {
          String[] retValue= new String[0];
          retValue[0]= __serviceName;
          return retValue;
      } 
  }

TestServiceProvider implements __getServiceFactory() and __writeRegistryServiceInfo():

  package JavaComp;
  ...
  public class TestServiceProvider
  {
      public static XSingleServiceFactory __getServiceFactory(String implName,
                                               XMultiServiceFactory multiFactory,
                                               XRegistryKey regKey) {
          XSingleServiceFactory xSingleServiceFactory = null;
 
          if (implName.equals( TestComponentA.class.getName()) )
              xSingleServiceFactory = FactoryHelper.getServiceFactory( TestComponentA.class,
                                          TestComponentA.__serviceName, multiFactory, regKey); 
          else if (implName.equals(TestComponentB.class.getName()))
              xSingleServiceFactory= FactoryHelper.getServiceFactory( TestComponentB.class,
                                          TestComponentB.__serviceName, multiFactory, regKey);
          return xSingleServiceFactory;
      }
 
      public static boolean __writeRegistryServiceInfo(XRegistryKey regKey){
          boolean bregA= FactoryHelper.writeRegistryServiceInfo( TestComponentA.class.getName(),
                                          TestComponentA.__serviceName, regKey);
          boolean bregB= FactoryHelper.writeRegistryServiceInfo( TestComponentB.class.getName(),
                                          TestComponentB.__serviceName, regKey);
          return bregA && bregB;
      } 
  }

The corresponding manifest entry must point to the static class with the component operations, in this case JavaComp.TestServiceProvider:

 RegistrationClassName: JavaComp.TestServiceProvider

Additional UNO Types

To make the Java UNO runtime more robust and efficient, each component is loaded with its own class loader, with one UnoClassLoader at the root that takes care of loading all Java classes representing UNO types in such a way that they are available across the whole Java UNO runtime environment.

If a Java UNO component requires additional UNO types, it must use a UNO-Type-Path manifest entry to specify the location of the UNO types. The UNO-Type-Path is similar to the Class-Path manifest entry and can contain URLs of jars and directories that contain the Java classes that represent additional UNO types. The UnoClassLoader evaluates the UNO-Type-Path manifest entry to ensure that the additional UNO types are available to the Java UNO environment. The UNO-Type-Path can have one of the following formats.

  • Current jar does not contain UNO types:
    UNO-Type-Path: 
    (Note the final space character.)
  • Current jar contains UNO types:
    UNO-Type-Path: <>
  • Current jar brings other jars that contain UNO types:
    UNO-Type-Path: any/other/jar.jar yet/another/jar.jar
  • Current jar and other jars that the current jar uses contain UNO types:
    UNO-Type-Path: any/other/jar.jar <> yet/another/jar.jar

Template:Documentation/Note

Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages