These files are now part of ridl.jar instead of jurt.jar,
so move them accordingly.
Follow-up cleanup for ae855bf481
Change-Id: I01df60d99f5296b6252b260f52160c3e62f4b8dc
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88007
Tested-by: Jenkins
Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>
440 lines
17 KiB
Java
440 lines
17 KiB
Java
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
package com.sun.star.comp.loader;
|
|
|
|
import java.lang.reflect.Method;
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.net.URLDecoder;
|
|
|
|
import com.sun.star.loader.CannotActivateFactoryException;
|
|
import com.sun.star.loader.XImplementationLoader;
|
|
|
|
import com.sun.star.registry.CannotRegisterImplementationException;
|
|
import com.sun.star.registry.XRegistryKey;
|
|
|
|
import com.sun.star.lang.XSingleComponentFactory;
|
|
import com.sun.star.lang.XSingleServiceFactory;
|
|
import com.sun.star.lang.XMultiServiceFactory;
|
|
import com.sun.star.lang.XServiceInfo;
|
|
import com.sun.star.lang.XInitialization;
|
|
|
|
import com.sun.star.uno.XComponentContext;
|
|
import com.sun.star.beans.XPropertySet;
|
|
import com.sun.star.util.XMacroExpander;
|
|
|
|
import com.sun.star.uno.Type;
|
|
import com.sun.star.uno.UnoRuntime;
|
|
|
|
import com.sun.star.lib.util.StringHelper;
|
|
|
|
import com.sun.star.uno.AnyConverter;
|
|
|
|
|
|
/**
|
|
* The <code>JavaLoader</code> class provides the functionality of the
|
|
* <code>com.sun.star.loader.Java</code> service.
|
|
*
|
|
* <p>Therefore the <code>JavaLoader</code> activates external UNO components
|
|
* which are implemented in Java.</p>
|
|
*
|
|
* <p>The loader is used by the <code>ServiceManger</code>.</p>
|
|
*
|
|
* @see com.sun.star.loader.XImplementationLoader
|
|
* @see com.sun.star.loader.Java
|
|
* @see com.sun.star.comp.servicemanager.ServiceManager
|
|
* @since UDK1.0
|
|
*/
|
|
public class JavaLoader implements XImplementationLoader,
|
|
XServiceInfo,
|
|
XInitialization
|
|
{
|
|
private static final boolean DEBUG = false;
|
|
|
|
private static final void DEBUG(String dbg) {
|
|
if (DEBUG) System.err.println( dbg );
|
|
}
|
|
|
|
private static String[] supportedServices = {
|
|
"com.sun.star.loader.Java"
|
|
};
|
|
|
|
protected XMultiServiceFactory multiServiceFactory = null;
|
|
|
|
private XMacroExpander m_xMacroExpander = null;
|
|
private static final String EXPAND_PROTOCOL_PREFIX = "vnd.sun.star.expand:";
|
|
|
|
/**
|
|
* Expands macrofied url using the macro expander singleton.
|
|
*/
|
|
private String expand_url( String url ) throws RuntimeException
|
|
{
|
|
if (url == null || !url.startsWith( EXPAND_PROTOCOL_PREFIX )) {
|
|
return url;
|
|
}
|
|
try {
|
|
if (m_xMacroExpander == null) {
|
|
XPropertySet xProps =
|
|
UnoRuntime.queryInterface(
|
|
XPropertySet.class, multiServiceFactory );
|
|
if (xProps == null) {
|
|
throw new com.sun.star.uno.RuntimeException(
|
|
"service manager does not support XPropertySet!",
|
|
this );
|
|
}
|
|
XComponentContext xContext = (XComponentContext)
|
|
AnyConverter.toObject(
|
|
new Type( XComponentContext.class ),
|
|
xProps.getPropertyValue( "DefaultContext" ) );
|
|
m_xMacroExpander = (XMacroExpander)AnyConverter.toObject(
|
|
new Type( XMacroExpander.class ),
|
|
xContext.getValueByName(
|
|
"/singletons/com.sun.star.util.theMacroExpander" )
|
|
);
|
|
}
|
|
// decode uric class chars
|
|
String macro = URLDecoder.decode(
|
|
StringHelper.replace(
|
|
url.substring( EXPAND_PROTOCOL_PREFIX.length() ),
|
|
'+', "%2B" ), "UTF-8" );
|
|
// expand macro string
|
|
String ret = m_xMacroExpander.expandMacros( macro );
|
|
if (DEBUG) {
|
|
System.err.println(
|
|
"JavaLoader.expand_url(): " + url + " => " +
|
|
macro + " => " + ret );
|
|
}
|
|
return ret;
|
|
} catch (com.sun.star.uno.Exception exc) {
|
|
throw new com.sun.star.uno.RuntimeException(exc,
|
|
exc.getMessage(), this );
|
|
} catch (java.lang.Exception exc) {
|
|
throw new com.sun.star.uno.RuntimeException(exc,
|
|
exc.getMessage(), this );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Default constructor.
|
|
*
|
|
* <p>Creates a new instance of the <code>JavaLoader</code> class.</p>
|
|
*/
|
|
public JavaLoader() {}
|
|
|
|
/**
|
|
* Creates a new <code>JavaLoader</code> object.
|
|
*
|
|
* <p>The specified <code>com.sun.star.lang.XMultiServiceFactory</code> is
|
|
* the <code>ServiceManager</code> service which can be delivered to all
|
|
* components the <code>JavaLoader</code> is loading.</p>
|
|
*
|
|
* <p>To set the <code>MultiServiceFactory</code> you can use the
|
|
* <code>com.sun.star.lang.XInitialization</code> interface, either.</p>
|
|
*
|
|
* @param factory the <code>ServiceManager</code>.
|
|
* @see com.sun.star.comp.servicemanager.ServiceManager
|
|
* @see com.sun.star.lang.XInitialization
|
|
*/
|
|
public JavaLoader(XMultiServiceFactory factory) {
|
|
multiServiceFactory = factory;
|
|
}
|
|
|
|
/**
|
|
* Unlike the original intention, the method could be called every time a
|
|
* new <code>com.sun.star.lang.XMultiServiceFactory</code> should be set at
|
|
* the loader.
|
|
*
|
|
* @param args - the first parameter (args[0]) specifies the <code>ServiceManager</code>.
|
|
* @see com.sun.star.lang.XInitialization
|
|
* @see com.sun.star.comp.servicemanager.ServiceManager
|
|
*/
|
|
public void initialize( java.lang.Object[] args )
|
|
throws com.sun.star.uno.Exception,
|
|
com.sun.star.uno.RuntimeException
|
|
{
|
|
if (args.length == 0)
|
|
throw new com.sun.star.lang.IllegalArgumentException("No arguments specified");
|
|
|
|
try {
|
|
multiServiceFactory = (XMultiServiceFactory) AnyConverter.toObject(
|
|
new Type(XMultiServiceFactory.class), args[0]);
|
|
} catch (ClassCastException castEx) {
|
|
throw new com.sun.star.lang.IllegalArgumentException(castEx,
|
|
"The argument must be an instance of XMultiServiceFactory");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Supplies the implementation name of the component.
|
|
*
|
|
* @return the implementation name - here the class name.
|
|
* @see com.sun.star.lang.XServiceInfo
|
|
*/
|
|
public String getImplementationName()
|
|
throws com.sun.star.uno.RuntimeException
|
|
{
|
|
return getClass().getName();
|
|
}
|
|
|
|
/**
|
|
* Verifies if a given service is supported by the component.
|
|
*
|
|
* @param serviceName the name of the service that should be checked.
|
|
* @return true,if service is supported - otherwise false.
|
|
*
|
|
* @see com.sun.star.lang.XServiceInfo
|
|
*/
|
|
public boolean supportsService(String serviceName)
|
|
throws com.sun.star.uno.RuntimeException
|
|
{
|
|
for (String supportedService : supportedServices) {
|
|
if (supportedService.equals(serviceName)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Supplies a list of all service names supported by the component.
|
|
*
|
|
* @return a String array with all supported services.
|
|
* @see com.sun.star.lang.XServiceInfo
|
|
*/
|
|
public String[] getSupportedServiceNames()
|
|
throws com.sun.star.uno.RuntimeException
|
|
{
|
|
return supportedServices;
|
|
}
|
|
|
|
/**
|
|
* Provides a components factory.
|
|
*
|
|
* <p>The <code>JavaLoader</code> tries to load the class first. If a
|
|
* location URL is given the RegistrationClassFinder is used to load the
|
|
* class. Otherwise the class is loaded through the Class.forName method.</p>
|
|
*
|
|
* <p>To get the factory the inspects the class for the optional static member
|
|
* functions __getServiceFactory resp. getServiceFactory (DEPRECATED).</p>
|
|
*
|
|
* @param implementationName the implementation (class) name of the component.
|
|
* @param implementationLoaderUrl the URL of the implementation loader. Not used.
|
|
* @param locationUrl points to an archive (JAR file) which contains a component.
|
|
* @param xKey registry key.
|
|
* @return the factory for the component (@see com.sun.star.lang.XSingleServiceFactory)
|
|
*
|
|
* @see com.sun.star.loader.XImplementationLoader
|
|
* @see com.sun.star.comp.loader.RegistrationClassFinder
|
|
*/
|
|
public java.lang.Object activate( String implementationName,
|
|
String implementationLoaderUrl,
|
|
String locationUrl,
|
|
XRegistryKey xKey )
|
|
throws CannotActivateFactoryException,
|
|
com.sun.star.uno.RuntimeException
|
|
{
|
|
locationUrl = expand_url( locationUrl );
|
|
|
|
Object returnObject = null;
|
|
Class<?> clazz ;
|
|
|
|
DEBUG("try to get factory for " + implementationName);
|
|
|
|
// First we must get the class of the implementation
|
|
// 1. If a location URL is given it is assumed that this points to a JAR file.
|
|
// The components class name is stored in the manifest file.
|
|
// 2. If only the implementation name is given, the class is loaded with the
|
|
// Class.forName() method. This is a hack to load bootstrap components.
|
|
// Normally a string must no be null.
|
|
try {
|
|
if ( locationUrl != null ) {
|
|
clazz = RegistrationClassFinder.find( locationUrl );
|
|
if (clazz == null) {
|
|
throw new CannotActivateFactoryException(
|
|
"Cannot activate jar " + locationUrl);
|
|
}
|
|
} else {
|
|
clazz = Class.forName( implementationName );
|
|
if (clazz == null) {
|
|
throw new CannotActivateFactoryException(
|
|
"Cannot find class " + implementationName);
|
|
}
|
|
}
|
|
} catch (java.net.MalformedURLException e) {
|
|
throw new CannotActivateFactoryException(e, "Can not activate factory because " + e);
|
|
} catch (java.io.IOException e) {
|
|
throw new CannotActivateFactoryException(e, "Can not activate factory because " + e);
|
|
} catch (java.lang.ClassNotFoundException e) {
|
|
throw new CannotActivateFactoryException(e, "Can not activate factory because " + e);
|
|
}
|
|
|
|
Class<?>[] paramTypes = {String.class, XMultiServiceFactory.class, XRegistryKey.class};
|
|
Object[] params = { implementationName, multiServiceFactory, xKey };
|
|
|
|
// try to get factory from implementation class
|
|
// latest style: use the public static method __getComponentFactory
|
|
// - new style: use the public static method __getServiceFactory
|
|
// - old style: use the public static method getServiceFactory ( DEPRECATED )
|
|
|
|
Method compfac_method = null;
|
|
try {
|
|
compfac_method = clazz.getMethod(
|
|
"__getComponentFactory", new Class [] { String.class } );
|
|
} catch ( NoSuchMethodException noSuchMethodEx) {
|
|
} catch ( SecurityException secEx) {
|
|
}
|
|
|
|
Method method = null;
|
|
if (null == compfac_method) {
|
|
try {
|
|
method = clazz.getMethod("__getServiceFactory", paramTypes);
|
|
} catch ( NoSuchMethodException noSuchMethodEx) {
|
|
} catch ( SecurityException secEx) {
|
|
}
|
|
}
|
|
|
|
try {
|
|
if (null != compfac_method) {
|
|
Object ret = compfac_method.invoke( clazz, new Object [] { implementationName } );
|
|
if (!(ret instanceof XSingleComponentFactory))
|
|
throw new CannotActivateFactoryException(
|
|
"No factory object for " + implementationName );
|
|
|
|
return ret;
|
|
}
|
|
else {
|
|
if ( method == null )
|
|
method = clazz.getMethod("getServiceFactory", paramTypes);
|
|
|
|
Object oRet = method.invoke(clazz, params);
|
|
|
|
if ( (oRet != null) && (oRet instanceof XSingleServiceFactory) )
|
|
returnObject = oRet;
|
|
}
|
|
} catch ( NoSuchMethodException e) {
|
|
throw new CannotActivateFactoryException(e, "Can not activate the factory for "
|
|
+ implementationName);
|
|
} catch ( SecurityException e) {
|
|
throw new CannotActivateFactoryException(e, "Can not activate the factory for "
|
|
+ implementationName);
|
|
} catch ( IllegalAccessException e ) {
|
|
throw new CannotActivateFactoryException(e, "Can not activate the factory for "
|
|
+ implementationName);
|
|
}
|
|
catch ( IllegalArgumentException e ) {
|
|
throw new CannotActivateFactoryException(e, "Can not activate the factory for "
|
|
+ implementationName);
|
|
} catch ( InvocationTargetException e ) {
|
|
throw new CannotActivateFactoryException(e, "Can not activate the factory for "
|
|
+ implementationName);
|
|
}
|
|
|
|
return returnObject;
|
|
}
|
|
|
|
/**
|
|
* Registers the component in a registry under a given root key.
|
|
*
|
|
* <p>If the component supports the optional
|
|
* methods __writeRegistryServiceInfo, writeRegistryServiceInfo (DEPRECATED),
|
|
* the call is delegated to that method. Otherwise a default registration
|
|
* will be accomplished.</p>
|
|
*
|
|
* @param regKey the root key under that the component should be registered.
|
|
* @param implementationLoaderUrl specifies the loader, the component is loaded by.
|
|
* @param locationUrl points to an archive (JAR file) which contains a component.
|
|
* @return true if registration is successfully - otherwise false.
|
|
*/
|
|
public boolean writeRegistryInfo( XRegistryKey regKey,
|
|
String implementationLoaderUrl,
|
|
String locationUrl )
|
|
throws CannotRegisterImplementationException,
|
|
com.sun.star.uno.RuntimeException
|
|
{
|
|
locationUrl = expand_url( locationUrl );
|
|
|
|
boolean success = false;
|
|
|
|
try {
|
|
|
|
Class<?> clazz = RegistrationClassFinder.find(locationUrl);
|
|
if (null == clazz)
|
|
throw new CannotRegisterImplementationException(
|
|
"Cannot determine registration class!" );
|
|
|
|
Class<?>[] paramTypes = { XRegistryKey.class };
|
|
Object[] params = { regKey };
|
|
|
|
Method method = clazz.getMethod("__writeRegistryServiceInfo", paramTypes);
|
|
Object oRet = method.invoke(clazz, params);
|
|
|
|
if ( (oRet != null) && (oRet instanceof Boolean) )
|
|
success = ((Boolean) oRet).booleanValue();
|
|
} catch (Exception e) {
|
|
throw new CannotRegisterImplementationException(e, e.toString());
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
/**
|
|
* Supplies the factory for the <code>JavaLoader</code>.
|
|
*
|
|
* @param implName the name of the desired component.
|
|
* @param multiFactory the <code>ServiceManager</code> is delivered to the factory.
|
|
* @param regKey not used - can be null.
|
|
* @return the factory for the <code>JavaLoader</code>.
|
|
*/
|
|
public static XSingleServiceFactory getServiceFactory( String implName,
|
|
XMultiServiceFactory multiFactory,
|
|
XRegistryKey regKey)
|
|
{
|
|
if ( implName.equals(JavaLoader.class.getName()) )
|
|
return new JavaLoaderFactory( multiFactory );
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Registers the <code>JavaLoader</code> at the registry.
|
|
*
|
|
* @param regKey root key under which the <code>JavaLoader</code> should be registered.
|
|
* @return true if registration succeeded - otherwise false.
|
|
*/
|
|
public static boolean writeRegistryServiceInfo(XRegistryKey regKey) {
|
|
boolean result = false;
|
|
|
|
try {
|
|
XRegistryKey newKey = regKey.createKey("/" + JavaLoader.class.getName() + "/UNO/SERVICE");
|
|
|
|
for (String supportedService : supportedServices) {
|
|
newKey.createKey(supportedService);
|
|
}
|
|
|
|
result = true;
|
|
} catch (Exception ex) {
|
|
if (DEBUG) System.err.println(">>>JavaLoader.writeRegistryServiceInfo " + ex);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|