Difference between revisions of "Documentation/DevGuide/WritingUNO/Implementing without Helpers"

From Apache OpenOffice Wiki
Jump to: navigation, search
m (1 revision(s))
m
Line 9: Line 9:
  
 
As soon as the component implements any UNO interface, <idl>com.sun.star.uno.XInterface</idl> is included automatically. The Java interface definition generated by javamaker for <idl>com.sun.star.uno.XInterface</idl> only contains a <code>TypeInfo</code> member used by Java UNO internally to store certain UNO type information:
 
As soon as the component implements any UNO interface, <idl>com.sun.star.uno.XInterface</idl> is included automatically. The Java interface definition generated by javamaker for <idl>com.sun.star.uno.XInterface</idl> only contains a <code>TypeInfo</code> member used by Java UNO internally to store certain UNO type information:
 
+
<source lang="java">
   // source file com/sun/star/uno/XInterface.java gcorresponding to the class generated by
+
   // source file com/sun/star/uno/XInterface.java corresponding to the class generated by
 
    
 
    
 
   package com.sun.star.uno;
 
   package com.sun.star.uno;
Line 19: Line 19:
 
       public static final com.sun.star.lib.uno.typeinfo.TypeInfo UNOTYPEINFO[] = null;
 
       public static final com.sun.star.lib.uno.typeinfo.TypeInfo UNOTYPEINFO[] = null;
 
   }
 
   }
 
+
</source>
 
Note that <code>XInterface</code> does not have any methods, in contrast to its IDL description. That means, if implements <code>com.sun.star.uno.XInterface</code> is added to a class definition, there is nothing to implement.  
 
Note that <code>XInterface</code> does not have any methods, in contrast to its IDL description. That means, if implements <code>com.sun.star.uno.XInterface</code> is added to a class definition, there is nothing to implement.  
  
The method <code>queryInterface()</code> is unnecessary in the implementation of a UNO object, because the Java UNO runtime environment obtains interface references without support from the UNO objects themselves. Within Java, the method <code>UnoRuntime.queryInterface()</code> is used to obtain interfaces instead of calling [http://api.openoffice.org/docs/common/ref/com/sun/star/uno/XInterface.html#queryInterface com.sun.star.uno.XInterface:queryInterface()], and the Java UNO language binding hands out interfaces for UNO objects to other processes on its own as well.
+
The method <code>queryInterface()</code> is unnecessary in the implementation of a UNO object, because the Java UNO runtime environment obtains interface references without support from the UNO objects themselves. Within Java, the method <code>UnoRuntime.queryInterface()</code> is used to obtain interfaces instead of calling <idlml>com.sun.star.uno.XInterface:queryInterface</idlml>(), and the Java UNO language binding hands out interfaces for UNO objects to other processes on its own as well.
  
 
The methods <code>acquire()</code> and <code>release()</code> are used for reference counting and control the lifetime of an object, because the Java garbage collector does this, there is no reference counting in Java components.
 
The methods <code>acquire()</code> and <code>release()</code> are used for reference counting and control the lifetime of an object, because the Java garbage collector does this, there is no reference counting in Java components.
Line 29: Line 29:
  
 
Helper classes with default <idl>com.sun.star.lang.XTypeProvider</idl> implementations are still under development for Java. Meanwhile, every Java UNO object implementation can implement the <code>XTypeProvider</code> interface as shown in the following code. In your implementation, adjust <code>getTypes()</code>: <!--[SOURCE:Components/Thumbs/org/openoffice/comp/test/ImageShrink.java]-->
 
Helper classes with default <idl>com.sun.star.lang.XTypeProvider</idl> implementations are still under development for Java. Meanwhile, every Java UNO object implementation can implement the <code>XTypeProvider</code> interface as shown in the following code. In your implementation, adjust <code>getTypes()</code>: <!--[SOURCE:Components/Thumbs/org/openoffice/comp/test/ImageShrink.java]-->
 
+
<source lang="java">
 
   ...
 
   ...
 
    
 
    
Line 61: Line 61:
 
    
 
    
 
   ...
 
   ...
 
+
</source>
 
The suggested implementation of the <code>getImplementationId()</code> method is not optimal, it uses the <code>hashCode()</code> of the first instance that initializes the static field. The future UNO helper class will improve this.
 
The suggested implementation of the <code>getImplementationId()</code> method is not optimal, it uses the <code>hashCode()</code> of the first instance that initializes the static field. The future UNO helper class will improve this.
  
Line 74: Line 74:
  
 
The registration and removal of listener interfaces is a standard procedure in Java. Some IDEs even create the necessary methods automatically. The following example could be written: <!--[SOURCE:Components/Thumbs/org/openoffice/comp/test/ImageShrink.java]-->
 
The registration and removal of listener interfaces is a standard procedure in Java. Some IDEs even create the necessary methods automatically. The following example could be written: <!--[SOURCE:Components/Thumbs/org/openoffice/comp/test/ImageShrink.java]-->
 
+
<source lang="java">
 
   ...
 
   ...
 
    
 
    
Line 130: Line 130:
 
       // ...
 
       // ...
 
   }
 
   }
 
+
</source>
 
{{PDL1}}
 
{{PDL1}}
 
[[Category: Writing UNO Components]]
 
[[Category: Writing UNO Components]]

Revision as of 21:20, 21 March 2008



XInterface

As soon as the component implements any UNO interface, com.sun.star.uno.XInterface is included automatically. The Java interface definition generated by javamaker for com.sun.star.uno.XInterface only contains a TypeInfo member used by Java UNO internally to store certain UNO type information:

  // source file com/sun/star/uno/XInterface.java corresponding to the class generated by
 
  package com.sun.star.uno;
 
  public interface XInterface
  {
      // static Member
      public static final com.sun.star.lib.uno.typeinfo.TypeInfo UNOTYPEINFO[] = null;
  }

Note that XInterface does not have any methods, in contrast to its IDL description. That means, if implements com.sun.star.uno.XInterface is added to a class definition, there is nothing to implement.

The method queryInterface() is unnecessary in the implementation of a UNO object, because the Java UNO runtime environment obtains interface references without support from the UNO objects themselves. Within Java, the method UnoRuntime.queryInterface() is used to obtain interfaces instead of calling <idlml>com.sun.star.uno.XInterface:queryInterface</idlml>(), and the Java UNO language binding hands out interfaces for UNO objects to other processes on its own as well.

The methods acquire() and release() are used for reference counting and control the lifetime of an object, because the Java garbage collector does this, there is no reference counting in Java components.

XTypeProvider

Helper classes with default com.sun.star.lang.XTypeProvider implementations are still under development for Java. Meanwhile, every Java UNO object implementation can implement the XTypeProvider interface as shown in the following code. In your implementation, adjust getTypes():

  ...
 
  // XTypeProvider implementation
 
  // maintain a static implementation id for all instances of ImageShrink
  // initialized by the first call to getImplementationId()
  protected static byte[] _implementationId;
 
  public com.sun.star.uno.Type[] getTypes() {
 
      // instantiate Type instances for each interface you support and place them in a Type[] array
      // (this object supports XServiceInfo, XTypeProvider, and XImageShrinkFilter)
      return new com.sun.star.uno.Type[] {
          new com.sun.star.uno.Type(com.sun.star.lang.XServiceInfo.class),
          new com.sun.star.uno.Type(com.sun.star.lang.XTypeProvider.class),
          new com.sun.star.uno.Type(org.openoffice.test.XImageShrinkFilter.class) };
  }
 
  synchronized public byte[] getImplementationId() {
      if (_implementationId == null) {
          _implementationId= new byte[16];
          int hash = hashCode(); // hashCode of this object
          _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;
  }
 
  ...

The suggested implementation of the getImplementationId() method is not optimal, it uses the hashCode() of the first instance that initializes the static field. The future UNO helper class will improve this.

XComponent

XComponent is an optional interface that is useful when other objects hold references to the component. The notification mechanism of XComponent enables listener objects to learn when the component stops to provide its services, so that the objects drop their references to the component. This enables the component to delete itself when its reference count drops to zero. From section Core Interfaces to Implement, there must be three things done when dispose() is called at an XComponent:

  • Inform registered XEventListeners that the object is being disposed of by calling their method disposing().
  • Release all references the object holds, including all XEvenListener objects.
  • On further calls to the component, throw an com.sun.star.lang.DisposedException in case the required task can not be fulfilled anymore, because the component was disposed.

In Java, the object cannot be deleted, but the garbage collector will do this. It is sufficient to release all references that are currently being held to break the cyclic reference, and to call disposing() on all com.sun.star.lang.XEventListeners.

The registration and removal of listener interfaces is a standard procedure in Java. Some IDEs even create the necessary methods automatically. The following example could be written:

  ...
 
  //XComponent implementation
 
  // hold a list of eventListeners
  private java.util.ArrayList eventListeners = new java.util.ArrayList();
 
  public void dispose {
      java.util.ArrayList listeners;
      synchronized (this) {
          listeners = eventListeners;
          eventListeners = null;
      }
      for (java.util.Iterator i = listeners.iterator(); i.hasNext();) {
          fireDisposing((XEventListener) i.next());
      }
      releaseReferences();
  }
 
  public void addEventListener(XEventListener listener) {
      bool fire = false;
      synchronized (this) {
          if (eventListeners == null) {
              fire = true;
          } else {
              eventListeners.add(listener);
          }
      }
      if (fire) {
          fireDisposing(listener);
      }
  }
 
  public synchronized void removeEventListener(XEventListener listener) {
      if (eventListeners != null) {
          int i = eventListeners.indexOf(listener);
          if (i >= 0) {
              eventListeners.remove(i);
          }
      }
  }
 
  private void fireDisposing(XEventListener listener) {
      com.sun.star.uno.EventObject event = new com.sun.star.uno.EventObject(this);
      try {
          listener.disposing(event);
      } catch (com.sun.star.uno.DisposedException e) {
          // it is not an error if some listener is disposed simultaneously
      }
  }
 
  private void releaseReferences() {
      xComponentContext = null;
      // ...
  }
Content on this page is licensed under the Public Documentation License (PDL).
Personal tools