2017-03-26

14: To Understand the Sample UNO Extension (LibreOffice Extension or Apache OpenOffice Extension), Part One

<The previous article in this series | The table of contents of this series | The next article in this series>

Main body START

To Know How to Handle (Read or Write) LibreOffice or Apache OpenOffice Writer or Calc Documents via Extensions from Java or Macro Programs

We Need to Understand the Sample UNO Extension Well

-Hypothesizer

Now that we have learned basic concepts of UNO, we can understand the details of our sample UNO extension. Unless we understand the sample UNO extension well, we won't be able to put the sample to practical use for the purpose of developing our future UNO extensions.

-Rebutter

That would be so.

-Hypothesizer

We will understand the sample UNO extension by experiencing the making of it.

-Rebutter

All right.

We Create the Project

-Hypothesizer

We are going to create the project.

Under the directory that contains the common Gradle build scripts or the common Ant build files, we create a directory, 'hiUnoExtensionsUnoExtension', which is the project root directory. The directory name is arbitrary.

-Rebutter

It's a long name . . .

-Hypothesizer

Ah, I warn this at this opportunity: I use long names with few scruples. That isn't because I like long names, but because I don't like abbreviations very much. An abbreviation seems handy when I name something, but it can be confusing when I look at it when I have forgotten much about it after some time. For example, if I name it 'hiExtExt', what does 'Ext' mean? Extended? Exterior? External? Extinct? Extra? Extract? Extreme? Extinguisher? If I successfully understand it as 'Extension', what extension is it? Firefox extension? Eclipse extension? Java extension? . . . If someone has an excellent memory that remembers after a while what each abbreviation meant, it's fine: go ahead with abbreviations. Regrettably, I have a poor memory, which makes me avoid abbreviations as much as possible. So, don't worry about my long names: if someone likes them short, he or she can shorten them themselves.

-Rebutter

Fair enough.

-Hypothesizer

Then, we create the Gradle build script or the Ant build file of the project.

As for the Gradle build script, we write like this.

// # Change the target name
ext.TARGET_NAME = "thebiasplanet.hiunoextensionsunoextension.uno"

apply ("from": "../commonBuild01.gradle")

// # Change the default task
defaultTasks ("registerUnoExtension")
ext ({
 // Add this if necessary
 //CHECKSTYLE = "ON"
 // Add this if necessary
 //JAR_DEPLOY_DIRECTORY_NAME = "?"
 // Add this if necessary
 //WAR_DEPLOY_DIRECTORY_NAME = "?"
 // # Change this if necessary
 INCLUDED_JAR_FILE_NAMES = ["../unoUtilitiesToDisclose/target/thebiasplanet.unoutilities.jar"]
 // # Change this if necessary
 OTHER_CLASSES_PATHS = [JAVA_FILES_BASE_DIRECTORY_NAME, CLASSES_BASE_DIRECTORY_NAME, LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME + "/unoil.jar", LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME + "/jurt.jar", LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME + "/ridl.jar", LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME + "/juh.jar"]
 REFERENCED_PROJECT_DIRECTORY_NAMES = ["../unoUtilitiesToDisclose"]
})

apply ("from": "../commonBuild02.gradle")

We specify the target name, here 'thebiasplanet.hiunoextensionsunoextension.uno' and the default task, 'registerUnoExtension'. And we include the Jar file name of the UNO utilities project in the 'INCLUDED_JAR_FILE_NAMES' array, which makes the contents of that Jar file included in the Jar file of this sample UNO extension project.

-Rebutter

What is the target name used for?

-Hypothesizer

It's used for the name of the UNO data types merged registry file, the name of the Jar file, the name of the UNO extension file, and the name of the UNO components setting file.

-Rebutter

Hmm, I guess that those files will be explained later.

As for including the Jar file name of the UNO utilities project in the 'INCLUDED_JAR_FILE_NAMES' array, do you mean that the Jar file of the UNO utilities project is expanded in the Jar file of this sample UNO extension project?

-Hypothesizer

Yes.

-Rebutter

I guess, that makes the contents of the Jar file of the UNO utilities project duplicated when we register other UNO extensions.

-Hypothesizer

Yes. Actually, that doesn't cause particular troubles, but, honestly, that isn't beautiful. We can make Jar files shared by multiple UNO extensions, but that necessitates some settings in LibreOffice. We will do those settings in future articles.

-Rebutter

OK.

-Hypothesizer

And note Jar files under the 'LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME' directory included in the 'OTHER_CLASSES_PATHS' array. Those Jar files are UNO libraries. We need them to compile our Java sources, but aren't included in our Jar file because they are loaded by default at runtime.

-Rebutter

I see.

-Hypothesizer

As for the Ant build file, we write like this.

<?xml version="1.0" encoding="UTF-8"?>
<!-- # Change the project name and the default target -->
<project basedir="." name="thebiasplanet.hiunoextensionsunoextension.uno" default="registerUnoExtension">
 <import file="../commonBuild01.xml"/>
 
 <!-- Add this if necessary
 <property name="CHECKSTYLE" value="ON"/>
 -->
 
 <!-- Add this if necessary
 <property name="JAR_DEPLOY_DIRECTORY_NAME" value="?"/>
 -->
 
 <!-- Add this if necessary
 <property name="WAR_DEPLOY_DIRECTORY_NAME" value="?"/>
 -->
 
 <path id="INCLUDED_JAR_FILE_NAMES">
  <!-- # Add the pathelement if necessary
  <pathelement path="?"/>
  -->
  <pathelement path="../unoUtilitiesToDisclose/target/thebiasplanet.unoutilities.jar"/>
 </path>
 
 <path id="OTHER_CLASSES_PATHS">
  <!-- # Change the path if necessary -->
  <pathelement path="${JAVA_FILES_BASE_DIRECTORY_NAME}:${CLASSES_BASE_DIRECTORY_NAME}:${LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME}/unoil.jar:${LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME}/jurt.jar:${LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME}/ridl.jar:${LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME}/juh.jar"/>
 </path>
 
 <import file="../commonBuild02.xml"/>
</project>

We specify the project name, here 'thebiasplanet.hiunoextensionsunoextension.uno' and the default target, 'registerUnoExtension'. And we include the Jar file name of the UNO utilities project in the 'INCLUDED_JAR_FILE_NAMES' path, which makes the contents of that Jar file included in the Jar file of this sample UNO extension project.

And note Jar files under the 'LIBREOFFICE_CLASSES_BASE_DIRECTORY_NAME' directory included in the 'OTHER_CLASSES_PATHS' path. Those Jar files are UNO libraries. We need them to compile our Java sources, but aren't included in our Jar file because they are loaded by default at runtime.

-Rebutter

OK.

-Hypothesizer

Then, we create this directories hierarchy under the project directory.

/source
 /java
 /resource
 /unoIdl
-Rebutter

All right.

We Create a UNO Interface

-Hypothesizer

As we want to create a UNO component that implements a specific UNO interface, we will create the UNO interface. If our UNO component needs to implement only existing UNO interfaces, that isn't necessary, but in many cases, we would want to create our own UNO interfaces.

We name our UNO interface 'thebiasplanet.uno.hiunoextensionsunoextension.XHiUnoExtensions', which means we have to create the UNOIDL file, 'thebiasplanet/uno/hiunoextensionsunoextension/XHiUnoExtensions.idl', under the 'unoIdl' directory.

And we write this in the 'XHiUnoExtensions.idl' file.

// # Change the defined variable name START
#ifndef __thebiasplanet_uno_hiunoextensionsunoextension_XHiUnoExtensions_idl__
#define __thebiasplanet_uno_hiunoextensionsunoextension_XHiUnoExtensions_idl__
// # Change the defined variable name END

#include <com/sun/star/uno/XInterface.idl>
// # Add necessary idls START
#include <com/sun/star/lang/IllegalArgumentException.idl>
// # Add necessary idls END

// # Change the module name
module thebiasplanet { module uno { module hiunoextensionsunoextension {
 // # Change the interface name and the parent interface
 interface XHiUnoExtensions: com::sun::star::uno::XInterface
 {
  // # Add methods START
  string sayHi( [in] string p_name)
    raises (com::sun::star::lang::IllegalArgumentException);
  // # Add methods END
 };
}; }; };

#endif
-Rebutter

Hmm, . . .

-Hypothesizer

'#ifndef' ~ '#endif' block is for the code inside it not to be executed multiple times. The name defined can be anything if it's unique from other defined names.

In '#include' directives, <> is used when the included file is under the system include directory, but "" is used when the included file is under a user specific directory.

'com::sun::star::uno::XInterface' is the base UNO interface of our UNO interface. Our UNO interface inherits only one UNO interface, but if necessary, it can inherit multiple UNO interfaces. Note the '::' notation: in UNOIDL, modules are delimited by '::'.

The 'sayHi' method is the method of our UNO interface. Of course, our UNO interface can contain multiple methods, if necessary.

The '[in]' specification means that the argument is passed into the method, and the change to the argument from inside the method can't be seen from outside of the method.

-Rebutter

I understand that, but what if we specify it as '[out]'? I guess, Java can't handle '[out]' arguments.

-Hypothesizer

Actually, the '[out]' or '[inout]' argument is mapped to an array in Java. If the argument is '[out] string p_argument1', it's mapped to 'String [] p_argument1'.

-Rebutter

Oh, so, we set a value in 'p_argument1 [0]' inside the method.

-Hypothesizer

Yes.

-Rebutter

The data type, 'string' is mapped to 'java.lang.String' in Java, I presume?

-Hypothesizer

Yes. As for mappings of data types, refer the reference documents here.

-Rebutter

Oh, null isn't allowed for UNO strings.

-Hypothesizer

So, it seems.

And exceptions except 'RuntimeException's, that UNO components of the UNO interface may throw have to be declared in the 'raises' clause. 'RuntimeException's are instances of 'com.sun.star.uno.RuntimeException' or its descendants'.

-Rebutter

I see.

Main body END

References

  • Apache OpenOffice Wiki. (2014/01/02). Apache OpenOffice Developer's Guide. Retrieved from https://wiki.openoffice.org/wiki/Documentation/DevGuide/OpenOffice.org_Developers_Guide

<The previous article in this series | The table of contents of this series | The next article in this series>