Defining an Interface

From Apache OpenOffice Wiki
Jump to: navigation, search



Interfaces describe aspects of objects. To specify a new behavior for the component, start with an interface definition that comprises the methods offering the new behavior. Define a pair of plain get and set methods in a single step using the attribute instruction. Alternatively, choose to define your own operations with arbitrary arguments and exceptions by writing the method signature, and the exceptions the operation throws. We will first write a small interface definition with attribute instructions, then consider the resolve() method in XUNoUrlResolver.

Let us assume we want to contribute an ImageShrink component to OpenOffice.org to create thumbnail images for use in Apache OpenOffice tables. There is already a com.sun.star.document.XFilter interface offering methods supporting file conversion. In addition, a method is required to get and set the source and target directories, and the size of the thumbnails to create. It is common practice that a service and its prime interface have corresponding names, so our component shall have an org::openoffice::test::XImageShrink interface with methods to do so through get and set operations.

Attributes

The attribute instruction creates these operations for the experimental interface definition:

Look at the specification for our XImageShrink interface:

  #ifndef __org_openoffice_test_XImageShrink_idl__
  #define __org_openoffice_test_XImageShrink_idl__
  #include <com/sun/star/uno/XInterface.idl>
  #include <com/sun/star/awt/Size.idl>
 
  module org { module openoffice { module test {
 
  interface XImageShrink : com::sun::star::uno::XInterface 
  {
      [attribute] string SourceDirectory;
      [attribute] string DestinationDirectory;
      [attribute] com::sun::star::awt::Size Dimension;
  };
 
  }; }; };
 
  #endif

We protect the interface from being redefined using #ifndef, then added #include com.sun.star.uno.XInterface and the struct com.sun.star.awt.Size. These were found in the API reference using its global index. Our interface will be known in the org::openoffice::test module, so it is nested in the corresponding module instructions.

Define an interface using the interface instruction. It opens with the keyword interface, gives an interface name and derives the new interface from a parent interface (also called super interface). It then defines the interface body in braces. The interface instruction concludes with a semicolon.

In this case, the introduced interface is XImageShrink. By convention, all interface identifiers start with an X. Every interface must inherit from the base interface for all UNO interfaces XInterface or from one of its derived interfaces. The simple case of single inheritance is expressed by a colon : followed by the fully qualified name of the parent type. The fully qualified name of a UNOIDL type is its identifier, including all containing modules separated by the scope operator ::. Here we derive from com::sun::star::uno::XInterface directly. If you want to declare a new interface that inherits from multiple interfaces, you do not use the colon notation, but instead list all inherited interfaces within the body of the new interface:

  interface XMultipleInheritance {
     interface XBase1;
      interface XBase2;
  };
Documentation caution.png UNOIDL allows forward declaration of interfaces used as parameters, return values or struct members. However, an interface you want to derive from must be a fully defined interface.

After the super interface the interface body begins. It may contain attribute and method declarations, and, in the case of a multiple-inheritance interface, the declaration of inherited interfaces. Consider the interface body of XImageShrink. It contains three attributes and no methods. Interface methods are discussed below.

An attribute declaration opens with the keyword attribute in square brackets, then it gives a known type and an identifier for the attribute, and concludes with a semicolon.

In our example, the string attributes named SourceDirectory and DestinationDirectory and a com::sun::star::awt::Size attribute known as Dimension were defined:

  [attribute] string SourceDirectory;
  [attribute] string DestinationDirectory;
  [attribute] com::sun::star::awt::Size Dimension;

During code generation in Java and C++, the attribute declaration leads to pairs of get and set methods. For instance, the Java interface generated by javamaker from this type description contains the following six methods:

  // from attribute SourceDir
  public String getSourceDirectory();
  public void setSourceDirectory(String _sourcedir);
 
  // from attribute DestinationDir
  public String getDestinationDirectory();
  public void setDestinationDirectory(String _destinationdir);
 
  // from attribute Dimension
  public com.sun.star.awt.Size getDimension();
  public void setDimension(com.sun.star.awt.Size _dimension);

As an option, define that an attribute cannot be changed from the outside using a readonly flag. To set this flag, write [attribute, readonly]. The effect is that only a get() method is created during code generation, but not a set() method. Another option is to mark an attribute as bound; that flag is of interest when mapping interface attributes to properties, see Storing the Service Manager for Further Use and C++ Component.

Since OpenOffice.org 2.x, there can be exception specifications for attributes, individually for the operations of getting and setting an attribute:

  [attribute] long Age { 
      get raises (DatabaseException); // raised when retrieving the age from the database fails
      set raises (IllegalArgumentException, // raised when the new age is negative
                  DatabaseException); // raised when storing the new age in the database fails
  };

If no exception specification is given, only runtime exceptions may be thrown.

Methods

When writing a real component, define the methods by providing their signature and the exceptions they throw in the idl file. Our XUnoUrlResolver example above features a resolve() method taking a UNO URL and throwing three exceptions.

  interface XUnoUrlResolver: com::sun::star::uno::XInterface
  { 
      com::sun::star::uno::XInterface resolve( [in] string sUnoUrl ) 
          raises (com::sun::star::connection::NoConnectException, 
                    com::sun::star::connection::ConnectionSetupException, 
                    com::sun::star::lang::IllegalArgumentException); 
  };

The basic structure of a method is similar to C++ functions or Java methods. The method is defined giving a known return type, the operation name, an argument list in brackets () and if necessary, a list of the exceptions the method may throw. The argument list, the exception clause raises () and an optional [ oneway ] flag preceding the operation are special in UNOIDL.

  • Each argument in the argument list must commence with one of the direction flags [ in ], [ out ] or [ inout ] before a known type and identifier for the argument is given. The direction flag specifies how the operation may use the argument:
Direction Flags for Methods Description
in Specifies that the method shall evaluate the argument as input parameter, but it cannot change it.
out Specifies that the argument does not parameterize the method, instead the method uses the argument as output parameter.
inout Specifies that the operation is parameterized by the argument and that the method uses the argument as output parameter as well.
  • Try to avoid the [ inout ] and [ out ] qualifiers, as they are awkward to handle in certain language bindings, like the Java language binding. The argument list can be empty. Multiple arguments must be separated by commas.
  • Exceptions are given through an optional raises () clause containing a comma-separated list of known exceptions given by their full name. The presence of a raises() clause means that only the listed exceptions, com.sun.star.uno.RuntimeException and their descendants may be thrown by the implementation. By specifying exceptions for methods, the implementer of your interface can return information to the caller, thus avoiding possible error conditions.

If you prepend a [ oneway ] flag to an operation, the operation can be executed asynchronously if the underlying method invocation system does support this feature. For example, a UNO Remote Protocol (URP) bridge is such a system that supports oneway calls. A oneway operation can not have a return value, or out or inout parameters. It must not throw other exceptions than com.sun.star.uno.RuntimeException.

Documentation caution.png Although there are no general problems with the specification and the implementation of the UNO oneway feature, there are several API remote usage scenarios where oneway calls cause deadlocks in Apache OpenOffice. Therefore it is not recommended to introduce new oneway methods with new Apache OpenOffice UNO APIs.
Documentation caution.png You can not override an attribute or a method inherited from a parent interface, that would not make sense in an abstract specification anyway. Furthermore, overloading is not possible. The qualified interface identifier in conjunction with the name of the method creates a unique method name.
Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages