2017-04-09

16: To Understand the Sample UNO Extension (LibreOffice Extension or Apache OpenOffice Extension), Part Three

<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 Create the 'Global UNO Services' Provider

-Hypothesizer

Now, we will create the 'global UNO services' provider. The 'global UNO services' provider is a class that is necessary when we register global UNO services. In that case, we include a single 'global UNO services' provider in our UNO extension.

-Rebutter

What does it do, exactly?

-Hypothesizer

The 'global UNO services' provider has two static methods. A static method, '__writeRegistryServiceInfo', registers global UNO services into LibreOffice. And the other method, '__getComponentFactory', returns a 'single UNO component' UNO objects factory for a specified UNO component name.

-Rebutter

What is the 'single UNO component' UNO objects factory?

-Hypothesizer

That term isn't a term used in the reference documents, but when I try to make an understandable explanation, such a term seems required.

Well, the 'single UNO component' UNO objects factory is a UNO objects factory that is dedicated for a single UNO component.

-Rebutter

So, a 'single UNO component' UNO objects factory creates instances of only a specific UNO component?

-Hypothesizer

Yes. When we get a UNO object of a global UNO service from the global UNO services manager, first, a 'single UNO component' UNO objects factory is gotten for a UNO component of the global UNO service, then, a UNO object is gotten from the 'single UNO component' UNO objects factory.

-Rebutter

Ah-ha.

-Hypothesizer

We don't usually call those static methods explicitly ourselves; they are called by the UNO runtime.

-Rebutter

I see.

-Hypothesizer

As our 'global UNO services' provider is 'thebiasplanet.uno.hiunoextensionsunoextension.HiUnoExtensionsUnoExtensionGlobalServicesProvider', we create a Java source file, 'java/thebiasplanet/uno/hiunoextensionsunoextension/HiUnoExtensionsUnoExtensionGlobalServicesProvider.java', under the 'source' directory, and write this in the file.

// # Change the package name
package thebiasplanet.uno.hiunoextensionsunoextension;

import java.util.Map;
import java.util.HashMap;
import com.sun.star.lang.XSingleComponentFactory;
import com.sun.star.registry.XRegistryKey;
import thebiasplanet.unoutilities.serviceshandling.GlobalUnoServicesProviderUtility;

// # Change the class name
public class HiUnoExtensionsUnoExtensionGlobalServicesProvider {
 private static final Map <String, Object []> IMPLEMENTATION_CLASS_NAME_TO_IMPLEMENTATION_CLASS_AND_SERVICE_NAMES_ARRAY_MAP = new HashMap <String, Object []> ();
 static {
  // # Add implementation classes START
  HiUnoExtensionsImplementation.setThisClassToServicesProvider (IMPLEMENTATION_CLASS_NAME_TO_IMPLEMENTATION_CLASS_AND_SERVICE_NAMES_ARRAY_MAP);
  // # Add implementation classes END
 }
 
 public static XSingleComponentFactory __getComponentFactory (String p_implementationName) {
  return GlobalUnoServicesProviderUtility.getSingleComponentFactory (IMPLEMENTATION_CLASS_NAME_TO_IMPLEMENTATION_CLASS_AND_SERVICE_NAMES_ARRAY_MAP, p_implementationName);
 }
 
 public static boolean __writeRegistryServiceInfo (XRegistryKey p_registryKey) {
  return GlobalUnoServicesProviderUtility.writeServicesInformationToRegistry (IMPLEMENTATION_CLASS_NAME_TO_IMPLEMENTATION_CLASS_AND_SERVICE_NAMES_ARRAY_MAP, p_registryKey);
 }
}
-Rebutter

Hmm, . . .

-Hypothesizer

The static member, 'IMPLEMENTATION_CLASS_NAME_TO_IMPLEMENTATION_CLASS_AND_SERVICE_NAMES_ARRAY_MAP', contains necessary information for the 'global UNO services' provider to register UNO services. The information is retrieved from concerned UNO components, here, one UNO component, 'thebiasplanet.uno.hiunoextensionsunoextension.HiUnoExtensionsImplementation'.

-Rebutter

So, if we want to include another UNO component, we can call the method, 'setThisClassToServicesProvider' for the UNO component in the static block.

-Hypothesizer

Yes. The information doesn't particularly have to be contained in that member: it's OK if the two static methods are implemented appropriately.

The processing inside the static methods are delegated to the utility class, 'thebiasplanet.unoutilities.serviceshandling.GlobalUnoServicesProviderUtility', because they are the same for any 'global UNO services' provider.

-Rebutter

I see.

We Create the Jar Manifest Contents File

-Hypothesizer

We create a Jar manifest contents file, 'resource/MANIFEST.MF.addition', under the 'source' directory, and write this in the file.

Comment01: # Change the class name
RegistrationClassName: thebiasplanet.uno.hiunoextensionsunoextension.HiUnoExtensionsUnoExtensionGlobalServicesProvider
UNO-Type-Path: <>

'MANIFEST.MF.addition' is a file that contains contents to be added to the Jar manifest file.

-Rebutter

Um, . . . I understand the reason why the 'global UNO services' provider is specified: the UNO runtime has to know which is the 'global UNO services' provider in our UNO extension.

What does the line "UNO-Type-Path: <>" do?

-Hypothesizer

'UNO-Type-Path' specifies Jar files that contain Java classes that represent UNO data types that are used by the Jar file to which the manifest file belongs. '<>' means the Jar file to which the manifest file belongs.

-Rebutter

Where should those additional Jar files be? Do we have to put those Jar files in our UNO extension file?

-Hypothesizer

Honestly, I don't know. In fact, as we use another method to load common Jar files, we always specify '<>' or '', which means that no Jar files are used for additional UNO data types. Note that Jar files that contain standard UNO data types don't have to be specified: those Jar files are loaded by default.

-Rebutter

Do 'standard UNO data types' mean UNO data types that are included in LibreOffice?

-Hypothesizer

Yes.

-Rebutter

OK.

We Create the UNO Components Setting File

-Hypothesizer

We create the UNO components setting file, which specifies what UNO components are included in the UNO extension. And in the file, we also associate global UNO service names to UNO components that are registered as global UNO services.

The file is 'resource/thebiasplanet.hiunoextensionsunoextension.uno.components' under the 'source' directory, and write this in the file.

<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://openoffice.org/2010/uno-components">
 <!-- # Change the jar file uri -->
 <component loader="com.sun.star.loader.Java2" uri="thebiasplanet.hiunoextensionsunoextension.uno.jar">
  <!-- # Add service implementation class names -->
  <implementation name="thebiasplanet.uno.hiunoextensionsunoextension.HiUnoExtensionsImplementation">
   <!-- # Add service names -->
   <service name="thebiasplanet.uno.hiunoextensionsunoextension.HiUnoExtensions"/>
  </implementation>
 </component>
</components>
-Rebutter

Judging from the structure of the XML file, I guess that multiple Jar files can be included in one UNO extension.

-Hypothesizer

Perhaps. But I haven't confirmed the guess because I don't see any necessity to include multiple Jar files now.

-Rebutter

Ah-ha. And we can include multiple 'implementation' tags inside the 'component' tag.

-Hypothesizer

Yes. And note that in the XML file, the tag, 'component', corresponds to a Jar file, but in our terminology, 'UNO component', always corresponds to a UNO interface implementation. As the reference documents and the UNO software itself make the term, 'component', refer to multiple kinds of entities, such a discrepancy is inevitable.

-Rebutter

All right.

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>