2017-04-30

19: To Develop the Second Sample UNO Extension (LibreOffice Extension or Apache OpenOffice Extension) in a Different Structure, 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

What Is the Aim of Developing the Second Sample UNO Extension?

-Hypothesizer

As we have developed and understood the first UNO extension, we want to change the structure of the UNO extension and do some experiments. In fact, we won't change the first UNO extension, but develop the second UNO extension in a different structure.

-Rebutter

All right.

-Hypothesizer

Our aim is to do these things.

  1. Separate definitions of UNO data types to a dedicated project, and register the UNO data types merged registry file and the Jar file of the project directly into LibreOffice.
  2. Register the UNO utilities Jar file directly into LibreOffice.
  3. Create the core utilities project and register its Jar file directly into LibreOffice.
  4. Experiment to create and use a global UNO service without any 'global UNO service' instances factory.
  5. Experiment to create and use a UNO component that isn't registered as a UNO service.
  6. Experiment to create a UNO old-style service, create a 'global UNO service' instances factory for the UNO old-style service, and create instances of the UNO old-style service by the 'global UNO service' instances factory.
  7. Experiment to directly cast an instance of a made-in-Java UNO object into a UNO interface without using the UnoRuntime.queryInterface method.
  8. Experiment to create a singleton factory of the UNO old-style service.

In fact, artifacts in the final form are here.

-Rebutter

OK. Without commenting about those items here, let's go through them one by one.

We Create the UNO Data Types Project and Register the UNO Data Types Merged Registry File and the Jar File of the Project Directly into LibreOffice

-Hypothesizer

According to the item, No. 1, we create the UNO data types project, 'unoAdditionalDataTypesToDisclose'.

We create the project directory directly under the development directory, which is the directory that holds common Gradle build scripts or Ant build files.

-Rebutter

So, we create the project directory at the same level with the first sample UNO extension project in the directories hierarchy.

-Hypothesizer

Yes. We always create project directories at the same level.

Then, we create the project-specific Gradle build script or Ant build file directly under the project directory. The contents of the Gradle build script is this.

// # Change the value
ext.TARGET_NAME = "thebiasplanet.unoadditionaldatatypes.uno"

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

// # Change the value
defaultTasks ("makeJar")
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 = []
 // # 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 = []
})

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

Note that the default task is 'makeJar'.

We won't explain about Ant build scripts any more because they are obvious from explanations about Gradle build scripts.

-Rebutter

OK.

-Hypothesizer

Then we create the 'source' directory directly under the project directory and create a UNO interface UNOIDL file, 'unoIdl/thebiasplanet/uno/heyunoextensionsunoextension/XHeyUnoExtensions.idl', under the 'source' directory.

The contents of the UNO interface UNOIDL file is this.

// # Change the defined variable name START
#ifndef __thebiasplanet_uno_heyunoextensionsunoextension_XHeyUnoExtensions_idl__
#define __thebiasplanet_uno_heyunoextensionsunoextension_XHeyUnoExtensions_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 heyunoextensionsunoextension {
 // # Change the interface name and the parent interface
 interface XHeyUnoExtensions: com::sun::star::uno::XInterface
 {
  // # Add methods START
  string sayHey ( [in] string p_name)
    raises (com::sun::star::lang::IllegalArgumentException);
  // # Add methods END
 };
}; }; };

#endif
-Rebutter

Well, basically, the structure is the same with that of the first sample.

-Hypothesizer

Yes. However, we will add some methods later. We will also add some UNO interfaces later.

-Rebutter

I see.

-Hypothesizer

Although this isn't the final format, we build the project by opening a terminal and changing the current directory to the project directory, and executing the 'gradle' command or the 'ant' command.

-Rebutter

Ah-ha, the command has finished successfully.

-Hypothesizer

In the target directory, there must be the UNO data types merged registry file, 'thebiasplanet.unoadditionaldatatypes.uno.rdb', and the Jar file, 'thebiasplanet.unoadditionaldatatypes.uno.jar'.

We create symbolic links in some LibreOffice directories to those files like this.

On Linux:

Open a terminal, and execute these commands (fill the '???' according to the environment, and change the directory of LibreOffice if necessary).

cd /usr/lib/libreoffice/program/types
sudo ln -s /???/unoAdditionalDataTypesToDisclose/target/thebiasplanet.unoadditionaldatatypes.uno.rdb ./thebiasplanet.unoadditionaldatatypes.uno.rdb
cd ../classes
sudo ln -s /???/unoAdditionalDataTypesToDisclose/target/thebiasplanet.unoadditionaldatatypes.uno.jar ./thebiasplanet.unoadditionaldatatypes.uno.jar

On Windows:

Open a command prompt as administrator (right click the command prompt item under the 'Start' menu, and click 'Run as administrator'), and execute these commands (fill the '?' and '???' according to the environment, and change the drive letter and the directory of LibreOffice if necessary).

D:
cd \LibreOffice\program\types
mklink .\thebiasplanet.unoadditionaldatatypes.uno.rdb ?:\???\unoAdditionalDataTypesToDisclose\target\thebiasplanet.unoadditionaldatatypes.uno.rdb
cd ..\classes
mklink .\thebiasplanet.unoadditionaldatatypes.uno.jar ?:\???\unoAdditionalDataTypesToDisclose\target\thebiasplanet.unoadditionaldatatypes.uno.jar

We open a file, 'fundamentalrc' on Linux and 'fundamental.ini' on Windows, under the LibreOffice 'program' directory, and in the 'URE_MORE_JAVA_TYPES' parameter, add the symbolic link path of the Jar file, in fact, '${BRAND_BASE_DIR}/program/classes/thebiasplanet.unoadditionaldatatypes.uno.jar'. Note that file paths are separated by a space.

After the LibreOffice program process is restarted, those files must be registered into LibreOffice.

-Rebutter

Don't we have to put a setting into a file for the UNO data types merged registry file?

-Hypothesizer

No, we don't. Just creating the symbolic link makes it registered. On the other hand, the symbolic link for the Jar file isn't necessary if we set the original path of the Jar file into the file, 'fundamentalrc' or 'fundamental.ini'.

-Rebutter

I see.

-Hypothesizer

Note that when LibreOffice is updated, those settings may be lost. Maybe we should do those settings by a Linux shell script or a Windows batch file.

-Rebutter

Were those settings lost for our updates?

-Hypothesizer

Yes. On Linux, 'fundamentalrc' was replaced with the default file; on Windows, all the settings were lost.

-Rebutter

Hmm.

-Hypothesizer

Anyway, by registering UNO data types independently from UNO extensions, any UNO extension can access those UNO data types.

-Rebutter

Ah-ha.

We Register the UNO utilities Jar file directly into LibreOffice

-Hypothesizer

As for the item, No. 2, we do the same thing to the UNO utilities Jar file.

On Linux:

Open a terminal, and execute these commands (fill the '???' according to the environment, and change the directory of LibreOffice if necessary).

cd /usr/lib/libreoffice/program/classes
sudo ln -s /???/unoUtilitiesToDisclose/target/thebiasplanet.unoutilities.jar ./thebiasplanet.unoutilities.jar

On WIndows:

Open a command prompt as administrator (right click the command prompt item under the 'Start' menu, and click 'Run as administrator'), and execute these commands (fill the '?' and '???' according to the environment, and change the drive letter and the directory of LibreOffice if necessary).

D:
cd \LibreOffice\program\classes
mklink .\thebiasplanet.unoutilities.jar ?:\???\unoUtilitiesToDisclose\target\thebiasplanet.unoutilities.jar

And we open the file, 'fundamentalrc' on Linux and 'fundamental.ini' on Windows, under the LibreOffice 'program' directory, and in the 'URE_MORE_JAVA_TYPES' parameter, add the symbolic link path of the Jar file, in fact, '${BRAND_BASE_DIR}/program/classes/thebiasplanet.unoutilities.jar'. If we didn't create the symbolic link, we can just add the original file path of the Jar file.

-Rebutter

I understand.

We Create the core utilities project and register its Jar file directly into LibreOffice.

-Hypothesizer

According to the item, No. 3, we will create another project, the core utilities project, 'coreUtilitiesToDisclose'.

-Rebutter

What is that project?

-Hypothesizer

It's a project that contains utility classes that don't use UNO.

-Rebutter

Hmm, . . .

-Hypothesizer

Of course, technically, those classes can be contained in the UNO utilities project, but from the administrative point of view, they are separated from the UNO utilities project because they can be used by projects that don't use UNO at all.

-Rebutter

I see.

-Hypothesizer

I have created a Java class source file, 'java/thebiasplanet/coreutilities/messaging/Publisher.java', under the 'source' directory. This is a static-methods class that builds messages and show message boxes. I won't delve into the details of the class because they aren't the issues here.

And I won't explain the project-specific Gradle build script either, because there is nothing particular about it.

-Rebutter

All right.

-Hypothesizer

We build the project by the usual method, and register the Jar file in a different way.

-Rebutter

Um?

-Hypothesizer

On a LibreOffice program process, we click on the menu item, 'Tools'-'Options...'; in the newly opened dialog box, on the left side, select 'LibreOffice'-'Advanced'; on the right side, click the 'Class Path...' button; in the newly opened dialog box, click 'Add Archive...'; select the Jar file; click the 'OK' button; click the 'OK' button. We have to restart the LibreOffice program process.

-Rebutter

Can't we register the Jar file in the same way with the UNO utilities Jar file?

-Hypothesizer

Yes, we can. Just note that Java classes in Jar files registered in the former way can access Java classes in Jar files registered in the latter way, but not vice versa. And as all the UNO classes are registered in the former way, Java classes in Jar files registered in the latter way can't access any UNO functionality.

-Rebutter

So, Java classes in a Jar file registered in the latter way can be accessed by wider range of Java classes.

-Hypothesizer

That's the reason we register the core utilities Jar file in the latter way.

Main body END

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