Yesterday evening, I tried to find a way to register several UNO services implementations using regcomp. The problem is that the implementations have all been created using the uno-skeletonmaker tool and contained each their own static registration methods. However there was nothing to register all the services implementations in the same jar file.

This has lead me to write a class that will later be used in the Eclipse integration to help the users implement new services easily. Thus in the next version of the Eclipse integration, creating a new service will also imply to create its implementation skeleton and prepare it for regcomp

For those interested in the class I wrote for the registration of the services implementations, here is the code. As you can understand from the code, the implementation classes names are stored in a RegistrationHandler.classes file: one class name by line.

package org.openoffice.test.comp;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.lang.reflect.Method;
import java.util.ArrayList;

import com.sun.star.lang.XSingleComponentFactory;
import com.sun.star.registry.XRegistryKey;

public class RegistrationHandler {

    public static XSingleComponentFactory __getComponentFactory(
                                String sImplementationName ) {
        XSingleComponentFactory xFactory = null;

        Class[] classes = findServicesImplementationClasses();

        int i = 0;
        while (i < classes.length && xFactory == null) {
            Class clazz = classes[i];
            if ( sImplementationName.equals( clazz.getCanonicalName() ) ) {
                try {
                    Class[] getTypes = new Class[]{String.class};
                    Method getFactoryMethod = clazz.getMethod(
                                        "__getComponentFactory", getTypes);
                    Object o = getFactoryMethod.invoke(null, sImplementationName);
                   xFactory = (XSingleComponentFactory)o;
                } catch (Exception e) {
                    // Nothing to do: skip
                    System.err.println("Error happened");
                    e.printStackTrace();
                }
           }
           i++;
        }
        return xFactory;
    }

    public static boolean __writeRegistryServiceInfo(XRegistryKey xRegistryKey ) {

        Class[] classes = findServicesImplementationClasses();

        boolean success = true;
        int i = 0;
        while (i < classes.length && success) {
            Class clazz = classes[i];
            try {
                Class[] writeTypes = new Class[]{XRegistryKey.class};
                Method getFactoryMethod = clazz.getMethod(
                                      "__writeRegistryServiceInfo", writeTypes);
                Object o = getFactoryMethod.invoke(null, xRegistryKey);
                success = success && ((Boolean)o).booleanValue();
            } catch (Exception e) {
                success = false;
                e.printStackTrace();
            }
            i++;
        }
        return success;
    }

    private static Class[] findServicesImplementationClasses() {

        ArrayList<Class> classes = new ArrayList<Class>();

        InputStream in = RegistrationHandler.class.
                 getResourceAsStream("RegistrationHandler.classes");
        LineNumberReader reader = new LineNumberReader(new InputStreamReader(in));

        try {
            String line = reader.readLine();
            while (line != null) {
                if (!line.equals("")) {
                    line = line.trim();
                    try {
                        Class clazz = Class.forName(line);

                        Class[] writeTypes = new Class[]{XRegistryKey.class};
                        Class[] getTypes = new Class[]{String.class};

                        Method writeRegMethod = clazz.getMethod(
                                "__writeRegistryServiceInfo", writeTypes);
                        Method getFactoryMethod = clazz.getMethod(
                                "__getComponentFactory", getTypes);

                        if (writeRegMethod != null && getFactoryMethod != null) {
                            classes.add(clazz);
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                line = reader.readLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                reader.close();
                in.close();
            } catch (Exception e) {};
        }

        return classes.toArray(new Class[classes.size()]);
    }
}