Java 组件的可能结构

From Apache OpenOffice Wiki
< Zh‎ | Documentation
Revision as of 19:39, 4 July 2018 by Sancho (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search


组件的实现取决于实现程序的需求。以下示例显示了一些组合组件的方法。每个组件文件可以有一 个或多个实现的对象。


一个组件文件一个实现

如果一个组件文件实现一个服务,可以存在附加选项:

  • 使用带有直接添加到服务实现类的静态组件操作的平面结构。
  • 保存带有静态组件操作的实现名称的类,并使用内部类实现服务。


带有组件操作的实现类

实现类包含静态组件操作。以下示例在实现类 JavaComp.TestComponent: 中实现了接口 com.sun.star.test.XSomething

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

仅实现一个支持 XSomething 的服务的组件可以组合到一个类中,如下所示:

  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( ) {
          ...
      } 
  }

该类实现 XSomething 接口。IDL 说明和文档提供有关其功能的信息。该类还包含用于工厂创建和注册的函数,因此标明条目必须如下所示:

 RegistrationClassName: JavaComp.TestComponent


带有组件操作的实现类和内部实现类

要将组件实现为通过 __getServiceFactory() 提供服务工厂的内部类,该组件必须是静态内部类,否则 FactoryHelper 提供的工厂不能创建组件。SDK 随附的示例 com.sun.star.comp.demo.DemoComponent.java 中提供了内部实现类的示例。这里省略了 __getServiceFactory()__writeRegistryServiceInfo() 的实现,因为它们与上述带有组件操作的实现类相同。

  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) {
          ...
      }
 
  }

此实现结构的标明条目将再次指向带有静态组件操作的类:

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


一个组件文件多个实现

要在一个组件文件中组合多个服务实现,请在服务本身的类中实现每个服务,并添加包含静态组件操作的单独类。以下代码示例提供了两个服务:TestComponentATestComponentB,它们使用包含组件操作的单独静态类 TestServiceProvider 实现 XSomethingAXSomethingB 接口。


以下是 XSomethingAXSomethingB 的 UNOIDL 规范:

  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 实现 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 实现 XSomethingB。请注意,它将接收组件上下文和其构造函数中的初始化参数。

  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 实现 __getServiceFactory()__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;
      } 
  }


相应的标明条目必须指向带有组件操作的静态类,在此示例中,是 JavaComp.TestServiceProvider

 RegistrationClassName: JavaComp.TestServiceProvider


另外的 UNO 类型

为了使 JAVA UNO 运行时更加健硕和高效,每个组件由它自身的类载入器加载,而在最底层则由一个 UnoClassLoader 来监管所有的用于标识 UNO 类型的 JAVA 类,以便于这些类能在整个 JAVA UNO 运行时环境中可用。


如果一个 JAVA UNO 组件需要另外的 UNO 类型, 它必需用 manifest 中的UNO-Type-Path 项来指定 UNO 类型的路径。UNO-Type-Path 与 manifest 中的 Class-Path 项相似,能保存 jar 的 URLS 和包含用于表示另外的 UNO 类型的 Java 类库的文件路径。UnoClassLoader 使用 manifest 中 UNO-Type-Path 的值以确保另外的 UNO 类型在 Java UNO 环境中可用。UNO-Type-Path 可以是以下其中一种格式:

  • 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
Documentation note.png 注意:基于向后兼容性的考虑,如果您完全没有设置 UNO-Type-Path 项, UNO 运行时会假设当前的 jar 不包含另外的 UNO 类型。
Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages