diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /javaunohelper | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'javaunohelper')
30 files changed, 4842 insertions, 0 deletions
diff --git a/javaunohelper/BUCK b/javaunohelper/BUCK new file mode 100644 index 000000000..a33df7b9d --- /dev/null +++ b/javaunohelper/BUCK @@ -0,0 +1,21 @@ +genrule( + name = 'juh-src', + cmd = ' && '.join([ + 'cd $TMP', + 'echo "FAKE SOURCE ARCHIVE" > README', + 'zip -qr $OUT *', + ]), + out = 'juh-src.jar', + visibility = ['PUBLIC'], +) + +genrule( + name = 'juh-javadoc', + cmd = ' && '.join([ + 'cd $TMP', + 'echo "FAKE JAVADOC ARCHIVE" > README', + 'zip -qr $OUT *', + ]), + out = 'juh-javadoc.jar', + visibility = ['PUBLIC'], +) diff --git a/javaunohelper/IwyuFilter_javaunohelper.yaml b/javaunohelper/IwyuFilter_javaunohelper.yaml new file mode 100644 index 000000000..d6ff3e6db --- /dev/null +++ b/javaunohelper/IwyuFilter_javaunohelper.yaml @@ -0,0 +1,16 @@ +--- +assumeFilename: javaunohelper/source/vm.cxx +excludelist: + javaunohelper/source/bootstrap.cxx: + # Needed for direct member access + - com/sun/star/uno/XComponentContext.hpp + - jvmaccess/unovirtualmachine.hxx + # Needed to avoid loplugin:unreffun error + - juhx-export-functions.hxx + javaunohelper/source/javaunohelper.cxx: + # Needed for direct member access + - com/sun/star/lang/XMultiServiceFactory.hpp + - com/sun/star/registry/XRegistryKey.hpp + - jvmaccess/unovirtualmachine.hxx + # Needed to avoid loplugin:unreffun error + - juhx-export-functions.hxx diff --git a/javaunohelper/Jar_juh.mk b/javaunohelper/Jar_juh.mk new file mode 100644 index 000000000..cf469200c --- /dev/null +++ b/javaunohelper/Jar_juh.mk @@ -0,0 +1,18 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# 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/. +# + +$(eval $(call gb_Jar_Jar,juh)) + +$(eval $(call gb_Jar_add_manifest_classpath,juh, \ + libreoffice.jar \ +)) + +$(eval $(call gb_Jar_set_manifest,juh,$(SRCDIR)/javaunohelper/util/manifest)) + +# vim:set noet sw=4 ts=4: diff --git a/javaunohelper/JunitTest_juh.mk b/javaunohelper/JunitTest_juh.mk new file mode 100644 index 000000000..e5ccfa1c4 --- /dev/null +++ b/javaunohelper/JunitTest_juh.mk @@ -0,0 +1,44 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# 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/. +# + +$(eval $(call gb_JunitTest_JunitTest,juh)) + +$(eval $(call gb_JunitTest_set_defs,juh,\ + $$(DEFS) \ + -XX:MaxGCPauseMillis=50 \ +)) + +$(eval $(call gb_JunitTest_use_jars,juh,\ + OOoRunner \ + libreoffice \ +)) + +$(eval $(call gb_JunitTest_use_jar_classset,juh,libreoffice)) + +$(eval $(call gb_JunitTest_add_sourcefiles,juh,\ + javaunohelper/test/com/sun/star/comp/helper/ComponentContext_Test \ + javaunohelper/test/com/sun/star/lib/uno/helper/AWeakBase \ + javaunohelper/test/com/sun/star/lib/uno/helper/ComponentBase_Test \ + javaunohelper/test/com/sun/star/lib/uno/helper/InterfaceContainer_Test \ + javaunohelper/test/com/sun/star/lib/uno/helper/MultiTypeInterfaceContainer_Test \ + javaunohelper/test/com/sun/star/lib/uno/helper/PropertySet_Test \ + javaunohelper/test/com/sun/star/lib/uno/helper/ProxyProvider \ + javaunohelper/test/com/sun/star/lib/uno/helper/WeakBase_Test \ +)) + +$(eval $(call gb_JunitTest_add_classes,juh,\ + com.sun.star.comp.helper.ComponentContext_Test \ + com.sun.star.lib.uno.helper.ComponentBase_Test \ + com.sun.star.lib.uno.helper.InterfaceContainer_Test \ + com.sun.star.lib.uno.helper.MultiTypeInterfaceContainer_Test \ + com.sun.star.lib.uno.helper.PropertySet_Test \ + com.sun.star.lib.uno.helper.WeakBase_Test \ +)) + +# vim:set noet sw=4 ts=4: diff --git a/javaunohelper/Library_juh.mk b/javaunohelper/Library_juh.mk new file mode 100644 index 000000000..aa7a4f105 --- /dev/null +++ b/javaunohelper/Library_juh.mk @@ -0,0 +1,35 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# 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/. +# + +$(eval $(call gb_Library_Library,juh)) + +$(eval $(call gb_Library_use_internal_comprehensive_api,juh,\ + udkapi \ +)) + +$(eval $(call gb_Library_use_libraries,juh,\ + sal \ +)) + +ifneq ($(DISABLE_DYNLOADING),TRUE) +$(eval $(call gb_Library_add_exception_objects,juh,\ + javaunohelper/source/preload \ +)) +else +# In the DISABLE_DYNLOADING case the juh library is a static archive that gets +# linked into the single .so, so we can put directly into it the code that in +# normal cases goes into the juhx library +$(eval $(call gb_Library_add_exception_objects,juh,\ + javaunohelper/source/bootstrap \ + javaunohelper/source/javaunohelper \ + javaunohelper/source/vm \ +)) +endif + +# vim:set noet sw=4 ts=4: diff --git a/javaunohelper/Library_juhx.mk b/javaunohelper/Library_juhx.mk new file mode 100644 index 000000000..1a24e5ef5 --- /dev/null +++ b/javaunohelper/Library_juhx.mk @@ -0,0 +1,30 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# 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/. +# + +$(eval $(call gb_Library_Library,juhx)) + +$(eval $(call gb_Library_use_internal_comprehensive_api,juhx,\ + udkapi \ +)) + +$(eval $(call gb_Library_use_libraries,juhx,\ + cppu \ + cppuhelper \ + jvmaccess \ + sal \ + salhelper \ +)) + +$(eval $(call gb_Library_add_exception_objects,juhx,\ + javaunohelper/source/bootstrap \ + javaunohelper/source/javaunohelper \ + javaunohelper/source/vm \ +)) + +# vim:set noet sw=4 ts=4: diff --git a/javaunohelper/Makefile b/javaunohelper/Makefile new file mode 100644 index 000000000..ccb1c85a0 --- /dev/null +++ b/javaunohelper/Makefile @@ -0,0 +1,7 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- + +module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST)))) + +include $(module_directory)/../solenv/gbuild/partial_build.mk + +# vim: set noet sw=4 ts=4: diff --git a/javaunohelper/Module_javaunohelper.mk b/javaunohelper/Module_javaunohelper.mk new file mode 100644 index 000000000..daafedaee --- /dev/null +++ b/javaunohelper/Module_javaunohelper.mk @@ -0,0 +1,31 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# 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/. +# + +$(eval $(call gb_Module_Module,javaunohelper)) + +ifneq ($(ENABLE_JAVA),) + +$(eval $(call gb_Module_add_targets,javaunohelper,\ + Library_juh \ + Jar_juh \ +)) + +$(eval $(call gb_Module_add_subsequentcheck_targets,javaunohelper,\ + JunitTest_juh \ +)) + +ifneq ($(DISABLE_DYNLOADING),TRUE) +$(eval $(call gb_Module_add_targets,javaunohelper,\ + Library_juhx \ +)) +endif + +endif + +# vim:set noet sw=4 ts=4: diff --git a/javaunohelper/README.md b/javaunohelper/README.md new file mode 100644 index 000000000..6b26e4aef --- /dev/null +++ b/javaunohelper/README.md @@ -0,0 +1,3 @@ +# Java UNO Helper + +Makes it easier to use UNO with Java. diff --git a/javaunohelper/pom.juh.xml b/javaunohelper/pom.juh.xml new file mode 100644 index 000000000..8bfcbab80 --- /dev/null +++ b/javaunohelper/pom.juh.xml @@ -0,0 +1,54 @@ +<project> + <modelVersion>4.0.0</modelVersion> + <groupId>org.libreoffice</groupId> + <artifactId>juh</artifactId> + <version>@version@</version> + <packaging>jar</packaging> + <name>LibreOffice - Java UNO helper</name> + <description>Java UNO helper</description> + <url>https://www.libreoffice.org</url> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.libreoffice</groupId> + <artifactId>libreoffice</artifactId> + <version>@version@</version> + </dependency> + </dependencies> + </dependencyManagement> + + <licenses> + <license> + <name>Mozilla Public License, Version 2.0</name> + <url>https://www.mozilla.org/en-US/MPL/2.0</url> + <distribution>repo</distribution> + </license> + </licenses> + + <scm> + <url>https://cgit.freedesktop.org/libreoffice/core</url> + <connection>https://gerrit.libreoffice.org/#/admin/projects/core</connection> + </scm> + + <developers> + <developer> + <name>The Document Foundation</name> + </developer> + </developers> + + <mailingLists> + <mailingList> + <name>LibreOffice Development Mailing List</name> + <post>libreoffice@lists.freedesktop.org</post> + <subscribe>http://lists.freedesktop.org/mailman/listinfo/libreoffice</subscribe> + <unsubscribe>http://lists.freedesktop.org/mailman/listinfo/libreoffice</unsubscribe> + <archive>http://lists.freedesktop.org/archives/libreoffice</archive> + </mailingList> + </mailingLists> + + <issueManagement> + <url>https://bugs.documentfoundation.org</url> + <system>LibreOffice Issue Tracker</system> + </issueManagement> +</project> diff --git a/javaunohelper/source/bootstrap.cxx b/javaunohelper/source/bootstrap.cxx new file mode 100644 index 000000000..1cacea950 --- /dev/null +++ b/javaunohelper/source/bootstrap.cxx @@ -0,0 +1,182 @@ +/* -*- Mode: C++; 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 . + */ + +#include <sal/config.h> +#include <sal/log.hxx> + +#include <osl/diagnose.h> + +#include <rtl/bootstrap.hxx> +#include <rtl/string.hxx> + +#include <uno/lbnames.h> +#include <uno/mapping.hxx> +#include <uno/environment.hxx> + +#include <cppuhelper/bootstrap.hxx> + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-attributes" +#endif +#include <jni.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +#include <jvmaccess/unovirtualmachine.hxx> + +#include "juhx-export-functions.hxx" +#include "vm.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace javaunohelper +{ + +static OUString jstring_to_oustring( jstring jstr, JNIEnv * jni_env ) +{ + OSL_ASSERT( sizeof (sal_Unicode) == sizeof (jchar) ); + jsize len = jni_env->GetStringLength( jstr ); + rtl_uString * ustr = + static_cast<rtl_uString *>(std::malloc( sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) )); + assert(ustr); + jni_env->GetStringRegion( jstr, 0, len, reinterpret_cast<jchar *>(ustr->buffer) ); + OSL_ASSERT( !jni_env->ExceptionCheck() ); + ustr->refCount = 1; + ustr->length = len; + ustr->buffer[ len ] = '\0'; + return OUString( ustr, SAL_NO_ACQUIRE ); +} + +} + + +jobject Java_com_sun_star_comp_helper_Bootstrap_cppuhelper_1bootstrap( + JNIEnv * jni_env, SAL_UNUSED_PARAMETER jclass, jstring juno_rc, jobjectArray jpairs, + jobject loader ) +{ + try + { + if (nullptr != jpairs) + { + jsize nPos = 0, len = jni_env->GetArrayLength( jpairs ); + while (nPos < len) + { + // name + jstring jstr = static_cast<jstring>(jni_env->GetObjectArrayElement( jpairs, nPos )); + if (jni_env->ExceptionCheck()) + { + jni_env->ExceptionClear(); + throw RuntimeException( "index out of bounds?!" ); + } + if (nullptr != jstr) + { + OUString name( ::javaunohelper::jstring_to_oustring( jstr, jni_env ) ); + // value + jstr = static_cast<jstring>(jni_env->GetObjectArrayElement( jpairs, nPos +1 )); + if (jni_env->ExceptionCheck()) + { + jni_env->ExceptionClear(); + throw RuntimeException( "index out of bounds?!" ); + } + if (nullptr != jstr) + { + OUString value( ::javaunohelper::jstring_to_oustring( jstr, jni_env ) ); + + // set bootstrap parameter + ::rtl::Bootstrap::set( name, value ); + } + } + nPos += 2; + } + } + + // bootstrap uno + Reference< XComponentContext > xContext; + if (nullptr == juno_rc) + { + xContext = ::cppu::defaultBootstrap_InitialComponentContext(); + } + else + { + OUString uno_rc( ::javaunohelper::jstring_to_oustring( juno_rc, jni_env ) ); + xContext = ::cppu::defaultBootstrap_InitialComponentContext( uno_rc ); + } + + // create vm access + ::rtl::Reference< ::jvmaccess::UnoVirtualMachine > vm_access( + ::javaunohelper::create_vm_access( jni_env, loader ) ); + // wrap vm singleton entry + xContext = ::javaunohelper::install_vm_singleton( xContext, vm_access ); + + // get uno envs + OUString cpp_env_name = CPPU_CURRENT_LANGUAGE_BINDING_NAME; + OUString java_env_name = UNO_LB_JAVA; + Environment java_env, cpp_env; + uno_getEnvironment(reinterpret_cast<uno_Environment **>(&cpp_env), cpp_env_name.pData, nullptr); + uno_getEnvironment(reinterpret_cast<uno_Environment **>(&java_env), java_env_name.pData, vm_access.get() ); + + // map to java + Mapping mapping( cpp_env.get(), java_env.get() ); + if (! mapping.is()) + { + Reference< lang::XComponent > xComp( xContext, UNO_QUERY ); + if (xComp.is()) + xComp->dispose(); + throw RuntimeException("cannot get mapping C++ <-> Java!" ); + } + + jobject jret = static_cast<jobject>(mapping.mapInterface( xContext.get(), cppu::UnoType<decltype(xContext)>::get() )); + jobject jlocal = jni_env->NewLocalRef( jret ); + jni_env->DeleteGlobalRef( jret ); + + return jlocal; + } + catch (const RuntimeException & exc) + { + jclass c = jni_env->FindClass( "com/sun/star/uno/RuntimeException" ); + if (nullptr != c) + { + SAL_WARN("javaunohelper", "forwarding RuntimeException: " << exc ); + OString cstr( OUStringToOString( + exc.Message, RTL_TEXTENCODING_JAVA_UTF8 ) ); + jni_env->ThrowNew( c, cstr.getStr() ); + } + } + catch (const Exception & exc) + { + jclass c = jni_env->FindClass( "com/sun/star/uno/Exception" ); + if (nullptr != c) + { + SAL_WARN("javaunohelper", "forwarding Exception: " << exc ); + OString cstr( OUStringToOString( + exc.Message, RTL_TEXTENCODING_JAVA_UTF8 ) ); + jni_env->ThrowNew( c, cstr.getStr() ); + } + } + + return nullptr; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/javaunohelper/source/javaunohelper.cxx b/javaunohelper/source/javaunohelper.cxx new file mode 100644 index 000000000..8db57c5b7 --- /dev/null +++ b/javaunohelper/source/javaunohelper.cxx @@ -0,0 +1,241 @@ +/* -*- Mode: C++; 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 . + */ + +#include <sal/config.h> + +#include <osl/module.hxx> + +#include <uno/environment.hxx> +#include <uno/lbnames.h> +#include <uno/mapping.hxx> + +#include <cppuhelper/factory.hxx> + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-attributes" +#endif +#include <jni.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +#include <jvmaccess/unovirtualmachine.hxx> + +#include "juhx-export-functions.hxx" +#include "vm.hxx" + +#ifdef DISABLE_DYNLOADING +#include <osl/thread.h> +#endif + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +/* + * Class: com_sun_star_comp_helper_SharedLibraryLoader + * Method: component_writeInfo + * Signature: (Ljava/lang/String;Lcom/sun/star/lang/XMultiServiceFactory;Lcom/sun/star/registry/XRegistryKey;)Z + */ +jboolean Java_com_sun_star_comp_helper_SharedLibraryLoader_component_1writeInfo( + JNIEnv * pJEnv, SAL_UNUSED_PARAMETER jclass, jstring jLibName, jobject jSMgr, + jobject jRegKey, jobject loader ) +{ + bool bRet = false; + + const jchar* pJLibName = pJEnv->GetStringChars(jLibName, nullptr); + OUString aLibName(reinterpret_cast<sal_Unicode const *>(pJLibName)); + pJEnv->ReleaseStringChars(jLibName, pJLibName); + +#ifdef DISABLE_DYNLOADING + (void) jSMgr; + (void) jRegKey; + (void) loader; + + fprintf(stderr, "Hmm, %s called for %s\n", __PRETTY_FUNCTION__, OUStringToOString(aLibName, osl_getThreadTextEncoding()).getStr()); +#else + osl::Module lib(aLibName, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL); + if (lib.is()) + { + // ========================= LATEST VERSION ========================= + oslGenericFunction pSym = lib.getFunctionSymbol(COMPONENT_GETENV); + if (pSym) + { + Environment java_env, loader_env; + + const char * pEnvTypeName = nullptr; + (*reinterpret_cast<component_getImplementationEnvironmentFunc>(pSym))( + &pEnvTypeName, reinterpret_cast<uno_Environment **>(&loader_env) ); + if (! loader_env.is()) + { + OUString aEnvTypeName( OUString::createFromAscii( pEnvTypeName ) ); + uno_getEnvironment( reinterpret_cast<uno_Environment **>(&loader_env), aEnvTypeName.pData, nullptr ); + } + + // create vm access + ::rtl::Reference< ::jvmaccess::UnoVirtualMachine > vm_access( + ::javaunohelper::create_vm_access( pJEnv, loader ) ); + OUString java_env_name = UNO_LB_JAVA; + uno_getEnvironment( + reinterpret_cast<uno_Environment **>(&java_env), java_env_name.pData, vm_access.get() ); + + pSym = lib.getFunctionSymbol(COMPONENT_WRITEINFO); + if (pSym) + { + if (loader_env.is() && java_env.is()) + { + Mapping java2dest(java_env.get(), loader_env.get()); + + if ( java2dest.is() ) + { + void * pSMgr = + java2dest.mapInterface( + jSMgr, cppu::UnoType<lang::XMultiServiceFactory>::get()); + void * pKey = + java2dest.mapInterface( + jRegKey, cppu::UnoType<registry::XRegistryKey>::get()); + + uno_ExtEnvironment * env = loader_env.get()->pExtEnv; + if (pKey) + { + bRet = (*reinterpret_cast<component_writeInfoFunc>(pSym))( pSMgr, pKey ); + + if (env) + (*env->releaseInterface)( env, pKey ); + } + + if (pSMgr && env) + (*env->releaseInterface)( env, pSMgr ); + } + } + } + } + lib.release(); + } +#endif + return bRet; +} + +/* + * Class: com_sun_star_comp_helper_SharedLibraryLoader + * Method: component_getFactory + * Signature: (Ljava/lang/String;Ljava/lang/String;Lcom/sun/star/lang/XMultiServiceFactory;Lcom/sun/star/registry/XRegistryKey;)Ljava/lang/Object; + */ +jobject Java_com_sun_star_comp_helper_SharedLibraryLoader_component_1getFactory( + JNIEnv * pJEnv, SAL_UNUSED_PARAMETER jclass, jstring jLibName, jstring jImplName, + jobject jSMgr, jobject jRegKey, jobject loader ) +{ + const jchar* pJLibName = pJEnv->GetStringChars(jLibName, nullptr); + OUString aLibName(reinterpret_cast<sal_Unicode const *>(pJLibName)); + pJEnv->ReleaseStringChars(jLibName, pJLibName); + +#ifdef DISABLE_DYNLOADING + (void) jImplName; + (void) jSMgr; + (void) jRegKey; + (void) loader; + + fprintf(stderr, "Hmm, %s called for %s\n", __PRETTY_FUNCTION__, OUStringToOString(aLibName, osl_getThreadTextEncoding()).getStr()); +#endif + + aLibName += SAL_DLLEXTENSION; + + jobject joSLL_cpp = nullptr; + +#ifndef DISABLE_DYNLOADING + osl::Module lib(aLibName, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL); + if (lib.is()) + { + // ========================= LATEST VERSION ========================= + oslGenericFunction pSym = lib.getFunctionSymbol(COMPONENT_GETENV); + if (pSym) + { + Environment java_env, loader_env; + + const char * pEnvTypeName = nullptr; + (*reinterpret_cast<component_getImplementationEnvironmentFunc>(pSym))( + &pEnvTypeName, reinterpret_cast<uno_Environment **>(&loader_env) ); + + if (! loader_env.is()) + { + OUString aEnvTypeName( OUString::createFromAscii( pEnvTypeName ) ); + uno_getEnvironment( reinterpret_cast<uno_Environment **>(&loader_env), aEnvTypeName.pData, nullptr ); + } + + // create vm access + ::rtl::Reference< ::jvmaccess::UnoVirtualMachine > vm_access( + ::javaunohelper::create_vm_access( pJEnv, loader ) ); + OUString java_env_name = UNO_LB_JAVA; + uno_getEnvironment( + reinterpret_cast<uno_Environment **>(&java_env), java_env_name.pData, vm_access.get() ); + + pSym = lib.getFunctionSymbol(COMPONENT_GETFACTORY); + if (pSym) + { + if (loader_env.is() && java_env.is()) + { + Mapping java2dest( java_env.get(), loader_env.get() ); + Mapping dest2java( loader_env.get(), java_env.get() ); + + if (dest2java.is() && java2dest.is()) + { + void * pSMgr = + java2dest.mapInterface( + jSMgr, cppu::UnoType<lang::XMultiServiceFactory>::get()); + void * pKey = + java2dest.mapInterface( + jRegKey, cppu::UnoType<registry::XRegistryKey>::get()); + + const char* pImplName = pJEnv->GetStringUTFChars( jImplName, nullptr ); + + void * pSSF = (*reinterpret_cast<component_getFactoryFunc>(pSym))( + pImplName, pSMgr, pKey ); + + pJEnv->ReleaseStringUTFChars( jImplName, pImplName ); + + uno_ExtEnvironment * env = loader_env.get()->pExtEnv; + + if (pKey && env) + (*env->releaseInterface)( env, pKey ); + if (pSMgr && env) + (*env->releaseInterface)( env, pSMgr ); + + if (pSSF) + { + jobject jglobal = static_cast<jobject>(dest2java.mapInterface( + pSSF, cppu::UnoType<XInterface>::get())); + joSLL_cpp = pJEnv->NewLocalRef( jglobal ); + pJEnv->DeleteGlobalRef( jglobal ); + if (env) + (*env->releaseInterface)( env, pSSF ); + } + } + } + } + } + lib.release(); + } +#endif + return joSLL_cpp; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/javaunohelper/source/juhx-export-functions.hxx b/javaunohelper/source/juhx-export-functions.hxx new file mode 100644 index 000000000..569822f2c --- /dev/null +++ b/javaunohelper/source/juhx-export-functions.hxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; 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 . + */ + +#ifndef INCLUDED_JAVAUNOHELPER_SOURCE_JUHX_EXPORT_FUNCTIONS_HXX +#define INCLUDED_JAVAUNOHELPER_SOURCE_JUHX_EXPORT_FUNCTIONS_HXX + +#include <sal/config.h> + +#include <sal/types.h> + +#include "juhx-export-types.hxx" + +extern "C" { + +SAL_JNI_EXPORT javaunohelper::detail::Func_bootstrap +Java_com_sun_star_comp_helper_Bootstrap_cppuhelper_1bootstrap; + +SAL_JNI_EXPORT javaunohelper::detail::Func_getFactory +Java_com_sun_star_comp_helper_SharedLibraryLoader_component_1getFactory; + +SAL_JNI_EXPORT javaunohelper::detail::Func_writeInfo +Java_com_sun_star_comp_helper_SharedLibraryLoader_component_1writeInfo; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/javaunohelper/source/juhx-export-types.hxx b/javaunohelper/source/juhx-export-types.hxx new file mode 100644 index 000000000..8e2783452 --- /dev/null +++ b/javaunohelper/source/juhx-export-types.hxx @@ -0,0 +1,52 @@ +/* -*- Mode: C++; 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 . + */ + +#ifndef INCLUDED_JAVAUNOHELPER_SOURCE_JUHX_EXPORT_TYPES_HXX +#define INCLUDED_JAVAUNOHELPER_SOURCE_JUHX_EXPORT_TYPES_HXX + +#include <sal/config.h> + +#include <jni.h> + +#if defined DISABLE_DYNLOADING +#define JAVAUNOHELPER_DETAIL_CALLCONV JNICALL +#else +#define JAVAUNOHELPER_DETAIL_CALLCONV +#endif + +extern "C" { + +namespace javaunohelper::detail { + +typedef jobject JAVAUNOHELPER_DETAIL_CALLCONV Func_bootstrap( + JNIEnv *_env, jclass, jstring, jobjectArray, jobject); + +typedef jobject JAVAUNOHELPER_DETAIL_CALLCONV Func_getFactory( + JNIEnv *, jclass, jstring, jstring, jobject, jobject, jobject); + +typedef jboolean JAVAUNOHELPER_DETAIL_CALLCONV Func_writeInfo( + JNIEnv *, jclass, jstring, jobject, jobject, jobject); + +} + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/javaunohelper/source/preload.cxx b/javaunohelper/source/preload.cxx new file mode 100644 index 000000000..f73b44b34 --- /dev/null +++ b/javaunohelper/source/preload.cxx @@ -0,0 +1,130 @@ +/* -*- Mode: C++; 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 . + */ + +#include <sal/config.h> + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-attributes" +#endif +#include <jni.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +#include <rtl/ustring.hxx> +#include <osl/module.hxx> + +#include "juhx-export-types.hxx" + +// In retrospect, the reason to create a juh wrapper around the juhx library was +// probably because java.lang.System.loadLibrary uses RTLD_LOCAL, so uniqueness +// of GCC RTTI symbols needed for exception handling would not be guaranteed. + +#if ! defined SAL_DLLPREFIX +#define SAL_DLLPREFIX "" +#endif + + +extern "C" +{ + +static javaunohelper::detail::Func_writeInfo * s_writeInfo; +static javaunohelper::detail::Func_getFactory * s_getFactory; +static javaunohelper::detail::Func_bootstrap * s_bootstrap; +static bool s_inited = false; + +extern "C" { static void thisModule() {} } + + +static bool inited_juhx( JNIEnv * jni_env ) +{ + if (s_inited) + return true; + osl::Module aModule; + if (!aModule.loadRelative(&thisModule, SAL_DLLPREFIX "juhx" SAL_DLLEXTENSION, SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL)) + { + jclass c = jni_env->FindClass( "java/lang/RuntimeException" ); + jni_env->ThrowNew( + c, "error loading " SAL_DLLPREFIX "juhx" SAL_DLLEXTENSION "!" ); + return false; + } + else + { + OUString symbol = + "Java_com_sun_star_comp_helper_SharedLibraryLoader_component_1writeInfo"; + s_writeInfo = reinterpret_cast<javaunohelper::detail::Func_writeInfo *>(aModule.getFunctionSymbol(symbol)); + symbol = + "Java_com_sun_star_comp_helper_SharedLibraryLoader_component_1getFactory"; + s_getFactory = reinterpret_cast<javaunohelper::detail::Func_getFactory *>(aModule.getFunctionSymbol(symbol)); + symbol = + "Java_com_sun_star_comp_helper_Bootstrap_cppuhelper_1bootstrap"; + s_bootstrap = + reinterpret_cast<javaunohelper::detail::Func_bootstrap *>(aModule.getFunctionSymbol(symbol)); + + if (nullptr == s_writeInfo || + nullptr == s_getFactory || + nullptr == s_bootstrap) + { + jclass c = jni_env->FindClass( "java/lang/RuntimeException" ); + jni_env->ThrowNew( + c, "error resolving symbols of " SAL_DLLPREFIX "juhx" SAL_DLLEXTENSION "!" ); + return false; + } + aModule.release(); + } + s_inited = true; + return true; +} + + +SAL_DLLPUBLIC_EXPORT jboolean JNICALL +Java_com_sun_star_comp_helper_SharedLibraryLoader_component_1writeInfo( + JNIEnv * pJEnv, jclass jClass, jstring jLibName, jobject jSMgr, + jobject jRegKey, jobject loader ) +{ + if (inited_juhx( pJEnv )) + return (*s_writeInfo)( + pJEnv, jClass, jLibName, jSMgr, jRegKey, loader ); + return JNI_FALSE; +} + +SAL_DLLPUBLIC_EXPORT jobject JNICALL +Java_com_sun_star_comp_helper_SharedLibraryLoader_component_1getFactory( + JNIEnv * pJEnv, jclass jClass, jstring jLibName, jstring jImplName, + jobject jSMgr, jobject jRegKey, jobject loader ) +{ + if (inited_juhx( pJEnv )) + return (*s_getFactory)( + pJEnv, jClass, jLibName, jImplName, jSMgr, jRegKey, loader ); + return nullptr; +} + +SAL_DLLPUBLIC_EXPORT jobject JNICALL +Java_com_sun_star_comp_helper_Bootstrap_cppuhelper_1bootstrap( + JNIEnv * jni_env, jclass jClass, jstring juno_rc, jobjectArray jpairs, + jobject loader ) +{ + if (inited_juhx( jni_env )) + return (*s_bootstrap)( jni_env, jClass, juno_rc, jpairs, loader ); + return nullptr; +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/javaunohelper/source/vm.cxx b/javaunohelper/source/vm.cxx new file mode 100644 index 000000000..e634c5596 --- /dev/null +++ b/javaunohelper/source/vm.cxx @@ -0,0 +1,113 @@ +/* -*- Mode: C++; 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 . + */ + + +#include <sal/config.h> + +#include "vm.hxx" + +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/lang/XSingleComponentFactory.hpp> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/component_context.hxx> +#include <cppuhelper/basemutex.hxx> +#include <jvmaccess/virtualmachine.hxx> +#include <jvmaccess/unovirtualmachine.hxx> + +namespace { + +typedef ::cppu::WeakComponentImplHelper< + css::lang::XSingleComponentFactory > t_impl; + +class SingletonFactory : public cppu::BaseMutex, public t_impl +{ + ::rtl::Reference< ::jvmaccess::UnoVirtualMachine > m_vm_access; + +protected: + virtual void SAL_CALL disposing() override; + +public: + explicit SingletonFactory( ::rtl::Reference< ::jvmaccess::UnoVirtualMachine > const & vm_access ) + : t_impl( m_aMutex ), + m_vm_access( vm_access ) + {} + + // XSingleComponentFactory impl + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithContext( + css::uno::Reference< css::uno::XComponentContext > const & xContext ) override; + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstanceWithArgumentsAndContext( + css::uno::Sequence< css::uno::Any > const & args, css::uno::Reference< css::uno::XComponentContext > const & xContext ) override; +}; + +void SingletonFactory::disposing() +{ + m_vm_access.clear(); +} + +css::uno::Reference< css::uno::XInterface > SingletonFactory::createInstanceWithContext( + css::uno::Reference< css::uno::XComponentContext > const & xContext ) +{ + sal_Int64 handle = reinterpret_cast< sal_Int64 >( m_vm_access.get() ); + css::uno::Any arg( css::beans::NamedValue( "UnoVirtualMachine", css::uno::Any( handle ) ) ); + return xContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.java.JavaVirtualMachine", + css::uno::Sequence< css::uno::Any >( &arg, 1 ), xContext ); +} + +css::uno::Reference< css::uno::XInterface > SingletonFactory::createInstanceWithArgumentsAndContext( + css::uno::Sequence< css::uno::Any > const & args, css::uno::Reference< css::uno::XComponentContext > const & xContext ) +{ + return xContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.java.JavaVirtualMachine", + args, xContext ); +} + +} + +namespace javaunohelper { + +::rtl::Reference< ::jvmaccess::UnoVirtualMachine > create_vm_access( + JNIEnv * jni_env, jobject loader ) +{ + JavaVM * vm; + jni_env->GetJavaVM( &vm ); + try { + return new ::jvmaccess::UnoVirtualMachine( + new ::jvmaccess::VirtualMachine( + vm, JNI_VERSION_1_2, false, jni_env ), + loader ); + } catch ( ::jvmaccess::UnoVirtualMachine::CreationException & ) { + throw css::uno::RuntimeException( "jvmaccess::UnoVirtualMachine::CreationException occurred" ); + } +} + +css::uno::Reference< css::uno::XComponentContext > install_vm_singleton( + css::uno::Reference< css::uno::XComponentContext > const & xContext, + ::rtl::Reference< ::jvmaccess::UnoVirtualMachine > const & vm_access ) +{ + css::uno::Reference< css::lang::XSingleComponentFactory > xFac( new SingletonFactory( vm_access ) ); + ::cppu::ContextEntry_Init entry( + "/singletons/com.sun.star.java.theJavaVirtualMachine", + css::uno::Any( xFac ), true ); + return ::cppu::createComponentContext( &entry, 1, xContext ); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/javaunohelper/source/vm.hxx b/javaunohelper/source/vm.hxx new file mode 100644 index 000000000..6681dfffa --- /dev/null +++ b/javaunohelper/source/vm.hxx @@ -0,0 +1,55 @@ +/* -*- Mode: C++; 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 . + */ + +#ifndef INCLUDED_JAVAUNOHELPER_SOURCE_VM_HXX +#define INCLUDED_JAVAUNOHELPER_SOURCE_VM_HXX + +#include <sal/config.h> + +#if defined __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-attributes" +#endif +#include <jni.h> +#if defined __clang__ +#pragma clang diagnostic pop +#endif + +#include <com/sun/star/uno/Reference.hxx> +#include <rtl/ref.hxx> + +namespace com::sun::star::uno { class XComponentContext; } +namespace jvmaccess { class UnoVirtualMachine; } + +namespace javaunohelper { + +::rtl::Reference< ::jvmaccess::UnoVirtualMachine > create_vm_access( + JNIEnv * jni_env, jobject loader ); + +css::uno::Reference< css::uno::XComponentContext > +install_vm_singleton( + css::uno::Reference< css::uno::XComponentContext > + const & xContext, + ::rtl::Reference< ::jvmaccess::UnoVirtualMachine > const & vm_access ); + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/javaunohelper/test/com/sun/star/comp/helper/Bootstrap_Test.java b/javaunohelper/test/com/sun/star/comp/helper/Bootstrap_Test.java new file mode 100644 index 000000000..9be051b62 --- /dev/null +++ b/javaunohelper/test/com/sun/star/comp/helper/Bootstrap_Test.java @@ -0,0 +1,113 @@ +/* + * 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.helper; + +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.AnyConverter; + +import com.sun.star.uno.XComponentContext; +import com.sun.star.lang.XComponent; +import com.sun.star.lang.XMultiServiceFactory; + +import java.util.logging.Logger; +import java.util.logging.Level; +import java.util.Map; + +public class Bootstrap_Test { + + private static final Logger logger = Logger.getLogger(Bootstrap_Test.class.getName()); + + public static boolean test( String ini_file, Map<String,String> bootstrap_parameters ) + throws java.lang.Exception + { + boolean passed = false; + logger.log(Level.INFO, "Bootstrap - doing tests..."); + + try { + XComponentContext xContext = + com.sun.star.comp.helper.Bootstrap.defaultBootstrap_InitialComponentContext( + ini_file, bootstrap_parameters ); + + if (AnyConverter.isVoid( + xContext.getValueByName( + "/singletons/com.sun.star.reflection.theTypeDescriptionManager" ) )) + { + throw new Exception( + "no /singletons/com.sun.star.reflection.theTypeDescriptionManager!" ); + } + + XMultiServiceFactory msf = UnoRuntime.queryInterface( + XMultiServiceFactory.class, xContext.getServiceManager() ); + String services[] = msf.getAvailableServiceNames(); + logger.log(Level.FINE, "Available services are:"); + if (services.length == 0) + logger.log(Level.FINE, "No services available!"); + + else + for ( int i=0; i<services.length; i++ ) + logger.log(Level.FINE, services[i]); + + XComponent xComp = UnoRuntime.queryInterface( + XComponent.class, xContext ); + xComp.dispose(); + + passed = true; + } + catch (Exception e) { + e.printStackTrace(); + } + logger.log(Level.INFO, "Bootstrap test passed? " + passed); + return passed; + } + + private static void usage() { + System.out.println(); + System.out.println("usage:"); + System.out.println("java com.sun.star.comp.helper.Bootstrap_Test ini-file name=value ..."); + System.out.println("example:"); + System.out.println("java com.sun.star.comp.helper.Bootstrap_Test file:///c:/ooo10/program/uno.ini SYSBINDIR=file:///c:/ooo10/program"); + System.exit( -1 ); + } + + public static void main(String args[]) throws java.lang.Exception { + if ( args.length == 0 ) + usage(); + + java.util.HashMap<String,String> bootstrap_parameters = new java.util.HashMap<String,String>(); + for ( int nPos = 1; nPos < args.length; ++nPos ) { + if (args[nPos].contains("=")) { + String bootstrap_parameter[] = args[nPos].split("=",2); + if (bootstrap_parameter[0].length() > 0) { + bootstrap_parameters.put( bootstrap_parameter[0], bootstrap_parameter[1] ); + } else { + System.out.println(); + System.out.println("The 1st argument in a bootstrap parameter is the key of a HashMap element and can't be null : '" + args[nPos] + "'"); + usage(); + } + } else { + System.out.println(); + System.out.println("Missing '=' in bootstrap parameter : '" + args[nPos] + "'"); + usage(); + } + } + + System.exit( test(args[0], bootstrap_parameters) ? 0: -1 ); + } +} + diff --git a/javaunohelper/test/com/sun/star/comp/helper/ComponentContext_Test.java b/javaunohelper/test/com/sun/star/comp/helper/ComponentContext_Test.java new file mode 100644 index 000000000..122ed2ce9 --- /dev/null +++ b/javaunohelper/test/com/sun/star/comp/helper/ComponentContext_Test.java @@ -0,0 +1,72 @@ +/* + * 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.helper; + +import java.util.HashMap; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.sun.star.lang.XComponent; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import org.junit.Test; + +public class ComponentContext_Test { + + private static final Logger logger = Logger.getLogger(ComponentContext_Test.class.getName()); + + @Test public void test() throws Exception { + logger.log(Level.INFO, "Testing ComponentContext"); + HashMap<String, Object> table = new HashMap<String, Object>(); + table.put("bla1", new ComponentContextEntry(null, Integer.valueOf(1))); + XComponentContext xInitialContext = Bootstrap.createInitialComponentContext(table); + + table = new HashMap<String, Object>(); + table.put("bla2", new ComponentContextEntry(Integer.valueOf(2))); + table.put("bla3", Integer.valueOf(3)); + XComponentContext xContext = new ComponentContext(table, xInitialContext); + + XMultiComponentFactory xSMgr = xContext.getServiceManager(); + + assertNotNull(xSMgr.createInstanceWithContext("com.sun.star.loader.Java", xContext)); + assertNotNull(xSMgr.createInstanceWithContext("com.sun.star.bridge.BridgeFactory", xContext)); + assertNotNull(xSMgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", xContext)); + assertNotNull(xSMgr.createInstanceWithContext("com.sun.star.connection.Connector", xContext)); + assertNotNull(xSMgr.createInstanceWithContext("com.sun.star.connection.Acceptor", xContext)); +// assertNotNull(xSMgr.createInstanceWithContext("com.sun.star.lang.ServiceManager", xContext)); + + assertNotNull(xContext.getValueByName("bla1")); + assertNotNull(xContext.getValueByName("bla2")); + assertNotNull(xContext.getValueByName("bla3")); + assertNotNull(xInitialContext.getValueByName("bla2")); + assertNotNull(xInitialContext.getValueByName("bla3")); + + assertEquals(((Integer) xContext.getValueByName("bla1")).intValue(), 1); + assertEquals(((Integer) xContext.getValueByName("bla2")).intValue(), 2); + assertEquals(((Integer) xContext.getValueByName("bla3")).intValue(), 3); + assertEquals(((Integer) xInitialContext.getValueByName("bla1")).intValue(), 1); + + XComponent xComp = UnoRuntime.queryInterface( + XComponent.class, xInitialContext); + xComp.dispose(); + } +}
\ No newline at end of file diff --git a/javaunohelper/test/com/sun/star/comp/helper/SharedLibraryLoader_Test.java b/javaunohelper/test/com/sun/star/comp/helper/SharedLibraryLoader_Test.java new file mode 100644 index 000000000..03daa113a --- /dev/null +++ b/javaunohelper/test/com/sun/star/comp/helper/SharedLibraryLoader_Test.java @@ -0,0 +1,165 @@ +/* + * 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.helper; + +import com.sun.star.uno.UnoRuntime; + +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XSingleServiceFactory; +import com.sun.star.loader.XImplementationLoader; + +import com.sun.star.registry.XSimpleRegistry; + +@Deprecated +public class SharedLibraryLoader_Test { + + private static final String NATIVE_SERVICE_MANAGER_IMP_NAME = "com.sun.star.comp.stoc.OServiceManager"; + private static final String NATIVE_SERVICE_MANAGER_LIB_NAME = "servicemgr.uno"; + private static final String NATIVE_REGISTRY_IMP_NAME = "com.sun.star.comp.stoc.SimpleRegistry"; + private static final String NATIVE_REGISTRY_LIB_NAME = "simplereg.uno"; + + private static XMultiServiceFactory nativeServiceManager = null; + private static XSingleServiceFactory sharedLibraryLoaderFactory = null; + private static XImplementationLoader sharedLibraryLoader = null; + private static XSimpleRegistry simpleRegistry = null; + + public static boolean test_getSharedLibraryLoaderFactory() + throws java.lang.Exception + { + sharedLibraryLoaderFactory = null; + System.out.println("*******************************************************************"); + System.out.println("Test: <<< get SharedLibraryLoader factory >>>"); + sharedLibraryLoaderFactory = SharedLibraryLoader.getServiceFactory(null, null); + + System.out.print("Test - "); + System.out.println(sharedLibraryLoaderFactory == null? "failed" : "successful"); + System.out.println("*******************************************************************"); + System.out.println(); + + return sharedLibraryLoaderFactory != null; + } + + public static boolean test_instantiateSharedLibraryLoader() + throws java.lang.Exception + { + sharedLibraryLoader = null; + System.out.println("*******************************************************************"); + System.out.println("Test: <<< instantiate SharedLibraryLoader >>>"); + if ( sharedLibraryLoaderFactory == null && ! test_getSharedLibraryLoaderFactory() ) + return false; + + sharedLibraryLoader = UnoRuntime.queryInterface( + XImplementationLoader.class, sharedLibraryLoaderFactory.createInstance() ); + + System.out.print("Test - "); + System.out.println(sharedLibraryLoader == null? "failed" : "successful"); + System.out.println("*******************************************************************"); + System.out.println(); + + return sharedLibraryLoader != null; + } + + public static boolean test_loadNativeServiceManager() + throws java.lang.Exception + { + nativeServiceManager = null; + + System.out.println("*******************************************************************"); + System.out.println("Test: <<< load native ServiceManager >>>"); + if ( sharedLibraryLoader == null && ! test_instantiateSharedLibraryLoader() ) + return false; + + System.err.println("- get the native ServiceManager factory"); + XSingleServiceFactory aSMgrFac = + UnoRuntime.queryInterface( XSingleServiceFactory.class, + sharedLibraryLoader.activate(NATIVE_SERVICE_MANAGER_IMP_NAME, null, NATIVE_SERVICE_MANAGER_LIB_NAME, null)); + + System.err.println("- instantiate the native ServiceManager"); + nativeServiceManager = UnoRuntime.queryInterface( XMultiServiceFactory.class, aSMgrFac.createInstance() ); + + System.out.print("Test - "); + System.out.println(nativeServiceManager == null? "failed" : "successful"); + + System.out.println("*******************************************************************"); + System.out.println(); + return nativeServiceManager != null; + } + + public static boolean test_loadNativeSimpleRegistry() + throws java.lang.Exception + { + System.out.println("*******************************************************************"); + System.out.println("Test: <<< load native SimpleRegistry >>>"); + if ( sharedLibraryLoader == null && ! test_instantiateSharedLibraryLoader() ) + return false; + + System.err.println("- get factory of the Registry"); + XSingleServiceFactory aRegFac = + UnoRuntime.queryInterface( XSingleServiceFactory.class, + sharedLibraryLoader.activate(NATIVE_REGISTRY_IMP_NAME, null, NATIVE_REGISTRY_LIB_NAME, null) + ); + System.err.println("- instantiate the Registry"); + simpleRegistry = + UnoRuntime.queryInterface( XSimpleRegistry.class, aRegFac.createInstance() ); + System.out.print("Test - "); + System.out.println(simpleRegistry == null? "failed" : "successful"); + System.out.println("*******************************************************************"); + System.err.println(); + return true; + } + + public static boolean test_registerSharedLibraryLoader() + throws java.lang.Exception + { + boolean result = true; + System.out.println("*******************************************************************"); + System.out.println("Test: <<< register SharedLibraryLoader at the Registry >>>"); + + if ( simpleRegistry == null && ! test_loadNativeSimpleRegistry() ) + return false; + + com.sun.star.registry.XRegistryKey regKey = simpleRegistry.getRootKey(); + result = SharedLibraryLoader.writeRegistryServiceInfo( null, regKey ); + + System.out.print("Test - "); + System.out.println( !result ? "failed" : "successful"); + System.out.println("*******************************************************************"); + System.out.println(); + return result; + } + + public static boolean test() throws java.lang.Exception { + boolean passed = true; + + System.err.println("SharedLibraryLoader - doing tests..."); + passed = test_getSharedLibraryLoaderFactory() && passed; + passed = test_instantiateSharedLibraryLoader() && passed; + passed = test_loadNativeServiceManager() && passed; + passed = test_loadNativeSimpleRegistry() && passed; + + System.err.println("SharedLibraryLoader test passed? " + passed); + + return passed; + } + + public static void main(String args[]) throws java.lang.Exception { + System.exit( test() ? 0: -1 ); + } +} + diff --git a/javaunohelper/test/com/sun/star/lib/uno/helper/AWeakBase.java b/javaunohelper/test/com/sun/star/lib/uno/helper/AWeakBase.java new file mode 100644 index 000000000..42ef8b1e0 --- /dev/null +++ b/javaunohelper/test/com/sun/star/lib/uno/helper/AWeakBase.java @@ -0,0 +1,33 @@ +/* + * 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.lib.uno.helper; +import com.sun.star.lang.XEventListener; + + +public class AWeakBase extends WeakBase implements XEventListener +{ + public int nDisposingCalled= 0; + + public void disposing(com.sun.star.lang.EventObject eventObject) + { + nDisposingCalled++; + } + +} + diff --git a/javaunohelper/test/com/sun/star/lib/uno/helper/ComponentBase_Test.java b/javaunohelper/test/com/sun/star/lib/uno/helper/ComponentBase_Test.java new file mode 100644 index 000000000..c67e95313 --- /dev/null +++ b/javaunohelper/test/com/sun/star/lib/uno/helper/ComponentBase_Test.java @@ -0,0 +1,109 @@ +/* + * 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.lib.uno.helper; + +import com.sun.star.uno.XWeak; +import com.sun.star.lang.XTypeProvider; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.lang.XEventListener; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import org.junit.Before; +import org.junit.Test; +import util.WaitUnreachable; + +public class ComponentBase_Test +{ + private static final Logger logger = Logger.getLogger(ComponentBase_Test.class.getName()); + AWeakBase obj1, obj2, obj3; + Object proxyObj1Weak1; + Object proxyObj3Weak1; + Object proxyObj3Weak2; + Object proxyObj3TypeProv; + Object proxyObj2TypeProv; + + /** Class variables are initialized before each Test method */ + @Before public void setUp() throws Exception + { + obj1= new AWeakBase(); + obj2= new AWeakBase(); + obj3= new AWeakBase(); + + proxyObj1Weak1= ProxyProvider.createProxy(obj1, XWeak.class); + proxyObj3Weak1= ProxyProvider.createProxy(obj3, XWeak.class); + proxyObj3Weak2= ProxyProvider.createProxy(obj3, XWeak.class); + assertNotNull(proxyObj1Weak1); + assertNotNull(proxyObj3Weak1); + assertNotNull(proxyObj3Weak2); + + proxyObj2TypeProv= ProxyProvider.createProxy(obj2, XTypeProvider.class); + proxyObj3TypeProv= ProxyProvider.createProxy(obj3, XTypeProvider.class); + assertNotNull(proxyObj2TypeProv); + assertNotNull(proxyObj3TypeProv); + } + + @Test public void test_dispose() throws Exception + { + logger.log(Level.INFO, "Testing ComponentBase: test_dispose()"); + ComponentBase comp= new ComponentBase(); + + logger.log(Level.FINE, "addEventListener"); + comp.addEventListener(obj1); + comp.addEventListener(obj2); + comp.addEventListener(obj3); + comp.addEventListener(UnoRuntime.queryInterface(XEventListener.class, proxyObj1Weak1)); + comp.addEventListener(UnoRuntime.queryInterface(XEventListener.class, proxyObj3Weak2)); + comp.addEventListener(UnoRuntime.queryInterface(XEventListener.class, proxyObj3TypeProv)); + obj1.nDisposingCalled = 0; + obj2.nDisposingCalled = 0; + obj3.nDisposingCalled = 0; + + comp.dispose(); + assertEquals(obj1.nDisposingCalled, 1); + assertEquals(obj2.nDisposingCalled, 1); + assertEquals(obj3.nDisposingCalled, 1); + + logger.log(Level.FINE, "Adding a listener after dispose, causes an immediate call to the listener."); + obj1.nDisposingCalled= 0; + comp.addEventListener(obj1); + assertEquals(obj1.nDisposingCalled, 1); + + logger.log(Level.FINE, "Calling dispose again must not notify the listeners again."); + obj1.nDisposingCalled= 0; + obj2.nDisposingCalled= 0; + obj3.nDisposingCalled= 0; + comp.dispose(); // already disposed; + assertEquals(obj1.nDisposingCalled, 0); + } + + @Test public void test_finalize() throws Exception + { + ComponentBase comp= new ComponentBase(); + obj1.nDisposingCalled = 0; + comp.addEventListener(obj1); + WaitUnreachable u = new WaitUnreachable(comp); + comp= null; + u.waitUnreachable(); + assertEquals(obj1.nDisposingCalled, 1); + } +} diff --git a/javaunohelper/test/com/sun/star/lib/uno/helper/Factory_Test.java b/javaunohelper/test/com/sun/star/lib/uno/helper/Factory_Test.java new file mode 100644 index 000000000..bb0a605eb --- /dev/null +++ b/javaunohelper/test/com/sun/star/lib/uno/helper/Factory_Test.java @@ -0,0 +1,194 @@ +/* + * 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.lib.uno.helper; + +import com.sun.star.uno.XComponentContext; +import com.sun.star.uno.Type; +import com.sun.star.uno.AnyConverter; +import com.sun.star.lang.XServiceInfo; +import com.sun.star.lang.XSingleComponentFactory; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XComponent; +import com.sun.star.beans.XPropertySet; +import com.sun.star.registry.XRegistryKey; +import com.sun.star.registry.XSimpleRegistry; +import com.sun.star.registry.XImplementationRegistration; +import com.sun.star.container.XSet; + +import com.sun.star.comp.helper.RegistryServiceFactory; +import com.sun.star.uno.UnoRuntime; + + +@Deprecated +public class Factory_Test + extends WeakBase + implements XServiceInfo +{ + static final String m_impl_name = Factory_Test.class.getName(); + static final String m_supported_services [] = { + "Factory_Test.Service0", "Factory_Test.Service1" }; + + + public Factory_Test() + { + } + + public Factory_Test( XComponentContext xContext ) + { + if (null == xContext.getValueByName( "/singletons/com.sun.star.lang.theServiceManager" )) + { + throw new com.sun.star.uno.RuntimeException( + "bad component context given!", this ); + } + } + + public static Object __create( XComponentContext xContext ) + { + return new Factory_Test( xContext ); + } + + // XServiceInfo impl + + public final String getImplementationName() + { + return m_impl_name; + } + + public final boolean supportsService( String service_name ) + { + for ( int nPos = 0; nPos < m_supported_services.length; ++nPos ) + { + if (m_supported_services[ nPos ].equals( service_name )) + return true; + } + return false; + } + + public final String [] getSupportedServiceNames() + { + return m_supported_services; + } + + + public static XSingleComponentFactory __getComponentFactory( String implName ) + { + if (implName.equals( m_impl_name )) + { + return Factory.createComponentFactory( + Factory_Test.class, Factory_Test.m_supported_services ); + } + return null; + } + + public static boolean __writeRegistryServiceInfo( XRegistryKey xKey ) + { + return Factory.writeRegistryServiceInfo( + m_impl_name, Factory_Test.m_supported_services, xKey ); + } + + + static void service_info_test( Object inst ) + { + XServiceInfo xInfo = UnoRuntime.queryInterface( XServiceInfo.class, inst ); + + if (! xInfo.getImplementationName().equals( m_impl_name )) + { + System.err.println( "Factory_Test: err -- 1" ); + System.exit( 1 ); + } + String supported_services [] = xInfo.getSupportedServiceNames(); + if (supported_services.length != m_supported_services.length) + { + System.err.println( "Factory_Test: err -- 2" ); + System.exit( 1 ); + } + for ( int nPos = 0; nPos < supported_services.length; ++nPos ) + { + if (! supported_services[ nPos ].equals( m_supported_services[ nPos ] )) + { + System.err.println( "Factory_Test: err -- 3" ); + System.exit( 1 ); + } + if (! xInfo.supportsService( m_supported_services[ nPos ] )) + { + System.err.println( "Factory_Test: err -- 4" ); + System.exit( 1 ); + } + } + } + + public static void main( String args [] ) + { + try + { + String jar = "file://" + new java.io.File( args[ 0 ] ).toURL().getPath(); + String rdb = "file://" + new java.io.File( args[ 1 ] ).toURL().getPath(); + System.out.println( "jar file = " + jar ); + System.out.println( "rdb file = " + rdb ); + + // bootstrap service manager + XMultiServiceFactory xMgr = RegistryServiceFactory.create( rdb ); + XPropertySet xProps = UnoRuntime.queryInterface( + XPropertySet.class, xMgr ); + XComponentContext xContext = (XComponentContext)AnyConverter.toObject( + new Type( XComponentContext.class ), xProps.getPropertyValue( "DefaultContext" ) ); + // insert java loader + XSet xSet = (XSet)AnyConverter.toObject( + new Type( XSet.class ), xContext.getServiceManager() ); + xSet.insert( new com.sun.star.comp.loader.JavaLoaderFactory( xMgr ) ); + // get rdb of smgr + XSimpleRegistry xRDB = (XSimpleRegistry)AnyConverter.toObject( + new Type( XSimpleRegistry.class ), xProps.getPropertyValue( "Registry" ) ); + // register impl + XImplementationRegistration xImpReg = + UnoRuntime.queryInterface( + XImplementationRegistration.class, + xContext.getServiceManager().createInstanceWithContext( + "com.sun.star.registry.ImplementationRegistration", xContext ) ); + xImpReg.registerImplementation( "com.sun.star.loader.Java2", jar, xRDB ); + + // tests + System.out.println( "testing instance" ); + service_info_test( new Factory_Test() ); + System.out.println( "testing instance" ); + service_info_test( new Factory_Test( xContext ) ); + System.out.println( "testing instance" ); + service_info_test( Factory_Test.__create( xContext ) ); + System.out.println( "testing factory __getComponentFactory()" ); + service_info_test( __getComponentFactory( m_impl_name ) ); + for ( int nPos = 0; nPos < m_supported_services.length; ++nPos ) + { + System.out.println( "testing factory " + m_supported_services[ nPos ] ); + service_info_test( + // create Service + xContext.getServiceManager().createInstanceWithContext( + m_supported_services[ nPos ], xContext ) ); + } + + XComponent xComp = UnoRuntime.queryInterface( XComponent.class, xContext ); + xComp.dispose(); + } + catch (Exception exc) + { + System.err.println( ">>>>>>>>>> exc occurred: " + exc.toString() ); + exc.printStackTrace(); + } + System.exit( 0 ); + } +} + diff --git a/javaunohelper/test/com/sun/star/lib/uno/helper/InterfaceContainer_Test.java b/javaunohelper/test/com/sun/star/lib/uno/helper/InterfaceContainer_Test.java new file mode 100644 index 000000000..a406b84d4 --- /dev/null +++ b/javaunohelper/test/com/sun/star/lib/uno/helper/InterfaceContainer_Test.java @@ -0,0 +1,661 @@ +/* + * 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.lib.uno.helper; + +import com.sun.star.uno.XWeak; +import com.sun.star.lang.XTypeProvider; +import com.sun.star.lib.uno.environments.java.java_environment; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.NoSuchElementException; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import org.junit.Before; +import org.junit.Test; + +public class InterfaceContainer_Test +{ + private static final Logger logger = Logger.getLogger(InterfaceContainer_Test.class.getName()); + java_environment env= new java_environment(null); + /** Creates a new instance of InterfaceContainerTest */ + AWeakBase obj1,obj2,obj3,obj4; + Object proxyObj1Weak1; + Object proxyObj3Weak1; + Object proxyObj3Weak2; + Object proxyObj3TypeProv; + Object proxyObj2TypeProv; + //contains original objects + List<Object> list1; + //contains original objects + proxies + List<Object> list2; + //contains original object + proxies + null value + List<Object> list3; + + /** Class variables are initialized before each Test method */ + @Before public void setUp() throws Exception + { + obj1= new AWeakBase(); + obj2= new AWeakBase(); + obj3= new AWeakBase(); + obj4= new AWeakBase(); + + proxyObj1Weak1= ProxyProvider.createProxy(obj1, XWeak.class); + proxyObj3Weak1= ProxyProvider.createProxy(obj3, XWeak.class); + proxyObj3Weak2= ProxyProvider.createProxy(obj3, XWeak.class); + assertNotNull(proxyObj1Weak1); + assertNotNull(proxyObj3Weak1); + assertNotNull(proxyObj3Weak2); + + proxyObj2TypeProv= ProxyProvider.createProxy(obj2, XTypeProvider.class); + proxyObj3TypeProv= ProxyProvider.createProxy(obj3, XTypeProvider.class); + assertNotNull(proxyObj2TypeProv); + assertNotNull(proxyObj3TypeProv); + + list1= new ArrayList<Object>(); + list1.add(obj1); + list1.add(obj2); + list1.add(obj3); + + list2= new ArrayList<Object>(); + list2.add(obj1); + list2.add(proxyObj2TypeProv); + list2.add(proxyObj3TypeProv); + + list3= new ArrayList<Object>(); + list3.add(obj1); + list3.add(null); + list3.add(proxyObj2TypeProv); + list3.add(proxyObj3Weak1); + } + + /** Tests add(object), size(), clear(); + */ + @Test public void add() throws Exception + { + logger.log(Level.INFO, "Testing List.add(Object), List.size(), List.clear(), List.isEmpty()"); + InterfaceContainer cont= new InterfaceContainer(); + + assertEquals(cont.size(), 0); + + assertTrue(cont.add(obj1)); + assertEquals(cont.size(), 1); + + assertTrue(cont.add(obj1)); // add the same object again + assertEquals(cont.size(), 2); + + assertTrue(cont.add(proxyObj3TypeProv)); + assertEquals(cont.size(), 3); + + assertFalse(cont.isEmpty()); + cont.clear(); + assertEquals(cont.size(), 0); + assertTrue(cont.isEmpty()); + } + + /**Tests list.addAll(Collection c), list.addAll(int index, Collection c) + */ + @Test public void listConstructors() throws Exception + { + logger.log(Level.INFO, "Testing Constructors of InterfaceContainer"); + InterfaceContainer cont= new InterfaceContainer(100); + + assertEquals(cont.elementData.length, 100); + } + + @Test public void trimToSize() throws Exception + { + logger.log(Level.INFO, "Testing InterfaceContainer.trimToSize"); + InterfaceContainer cont= new InterfaceContainer(100); + + cont.trimToSize(); + assertTrue(cont.isEmpty()); + cont= new InterfaceContainer(10); + cont.addAll(list1); + cont.trimToSize(); + assertEquals(cont.elementData.length, list1.size()); + } + + @Test public void ensureCapacity() throws Exception + { + logger.log(Level.INFO, "Testing InterfaceContainer.ensureCapacity"); + InterfaceContainer cont= new InterfaceContainer(10); + + cont.ensureCapacity(9); + assertTrue(cont.elementData.length >= 9); + + cont.ensureCapacity(11); + assertTrue(cont.elementData.length >= 11); + } + + @Test public void addAll() throws Exception + { + logger.log(Level.INFO, "Testing List.addAll(Collection c), List.addAll(int index, Collection c)"); + InterfaceContainer cont= new InterfaceContainer(); + + assertTrue(cont.addAll(list1)); + assertEquals(cont.size(), list1.size()); + for (int c= 0; c < cont.size(); c++) + { + assertSame(list1.get(c), cont.get(c)); + } + assertTrue(cont.add(obj1)); + assertTrue(cont.addAll(1, list2)); + assertSame(cont.get(0), list1.get(0)); + assertSame(cont.get(1), list2.get(0)); + assertSame(cont.get(2), list2.get(1)); + assertSame(cont.get(3), list2.get(2)); + assertSame(cont.get(4), list1.get(1)); + assertSame(cont.get(5), list1.get(2)); + assertSame(cont.get(6), obj1); + + cont.clear(); + cont.addAll(list3); + // the null element in list3 at index 1 is not added to cont + assertSame(cont.get(0), list3.get(0)); + assertSame(cont.get(1), list3.get(2)); + assertSame(cont.get(2), list3.get(3)); + } + + /** Tests List.add(int index, Object element), List.get(int index) + */ + @Test public void get() throws Exception + { + logger.log(Level.INFO, "Testing List.add(int index, Object element), List.get(int index)"); + InterfaceContainer cont= new InterfaceContainer(); + + cont.add(0, obj1); + cont.add(1, obj2); + cont.add(1, proxyObj3Weak1); + cont.add(3, obj3); + + assertSame(cont.get(0), obj1); + assertSame(cont.get(1), proxyObj3Weak1); + assertSame(cont.get(2), obj2); + assertSame(cont.get(3), obj3); + + try { + cont.add(5, obj1); + fail("IndexOutOfBoundsException expected"); + } catch (IndexOutOfBoundsException indexOutOfBoundsException) { + logger.log(Level.FINE, "IndexOutOfBoundsException caught"); + } + } + + /** Tests List.contains + */ + @Test public void contains() throws Exception + { + logger.log(Level.INFO, "Testing List.contains()"); + InterfaceContainer cont= new InterfaceContainer(); + + assertFalse(cont.contains(obj1)); // nothing in the list + + cont.add(obj1); + cont.add(proxyObj2TypeProv); + cont.add(proxyObj3TypeProv); + + assertTrue(cont.contains(obj1)); + assertTrue(cont.contains(obj2)); + assertTrue(cont.contains(proxyObj3Weak1)); + assertTrue(cont.contains(proxyObj3Weak2)); + assertTrue(cont.contains(proxyObj1Weak1)); + assertTrue(cont.contains(obj3)); + assertFalse(cont.contains(null)); + } + + /** Tests List.containsAll + */ + @Test public void containsAll() throws Exception + { + logger.log(Level.INFO, "Testing List.containsAll"); + InterfaceContainer cont= new InterfaceContainer(); + + cont.addAll(list1); + assertTrue(cont.containsAll(list1)); + + cont.clear(); + cont.addAll(list2); + assertTrue(cont.containsAll(list2)); + + cont.clear(); + cont.addAll(list3); // the null element in list3 is not added to cont + assertFalse(cont.containsAll(list3)); + + cont.clear(); + for( int x= 0; x < 6; x++) + cont.add(obj4); + assertFalse(cont.contains(list1)); + + cont.add(1, list1.get(0)); + cont.add(3, list1.get(1)); + cont.add(5, list1.get(2)); + assertFalse(cont.contains(list1)); + } + /** Tests List.indexOf, List.lastIndexOf + */ + @Test public void indexOf() throws Exception + { + logger.log(Level.INFO, "Testing List.indexOf(Object element), List.lastIndexOf(Object element)"); + InterfaceContainer cont= new InterfaceContainer(); + + cont.addAll(list1); + cont.addAll(list1); + assertEquals(cont.indexOf(obj3), 2); + assertEquals(cont.lastIndexOf(obj3), 5); + + cont.clear(); + cont.addAll(list2); + cont.addAll(list2); + assertEquals(cont.indexOf(proxyObj3Weak1), 2); + assertEquals(cont.lastIndexOf(proxyObj3Weak2), 5); + } + + /** Tests List.remove(int index), List.remove(Object element), List.removeAll(Collection c) + */ + @Test public void remove() throws Exception + { + logger.log(Level.INFO, "Testing List.remove(int index), List.remove(Object element), List.removeAll(Collection c)"); + InterfaceContainer cont= new InterfaceContainer(); + + cont.addAll(list2); + assertTrue(proxyObj2TypeProv.equals(cont.remove(1))); + assertEquals(cont.size(), 2); + + cont.clear(); + cont.addAll(list2); + assertTrue(cont.remove(obj1)); + assertTrue(cont.remove(proxyObj2TypeProv)); + assertTrue(cont.remove(proxyObj3Weak2)); + assertTrue(cont.isEmpty()); + + cont.clear(); + cont.addAll(list3); + assertTrue(cont.removeAll(list3)); + assertTrue(cont.isEmpty()); + + cont.addAll(list2); + List<Object> list= new ArrayList<Object>(); + list.add(list2.get(0)); + list.add(list2.get(1)); + list.add(proxyObj3Weak2); + assertTrue(cont.removeAll(list)); + assertTrue(cont.isEmpty()); + } + + /** Tests List.retainAll + */ + @Test public void retainAll() throws Exception + { + logger.log(Level.INFO, "Testing List.retainAll(Collection c)"); + InterfaceContainer cont= new InterfaceContainer(); + + cont.addAll(list1); //obj1, obj2, obj3 + cont.addAll(list2); //obj1, proxyObj2TypeProv, proxyObj3TypeProv + List<Object> list = new ArrayList<Object>(); + list.add(obj1); + list.add(proxyObj3Weak1); + + assertTrue(cont.retainAll(list)); + assertSame(cont.get(0), obj1); + assertSame(cont.get(1), obj3); + assertSame(cont.get(2), obj1); + assertSame(cont.get(3), proxyObj3TypeProv); + assertEquals(cont.size(), 4); + } + + /** Tests List.set(int index, Object element) + **/ + @Test public void set() throws Exception + { + logger.log(Level.INFO, "Testing List.set(int index, Object element)"); + InterfaceContainer cont= new InterfaceContainer(); + + cont.addAll(list2); + Object o1= cont.set(0, obj3); + Object o2= cont.set(2, proxyObj3Weak1); + + assertSame(list2.get(0), o1); + assertSame(list2.get(2), o2); + assertSame(cont.get(0), obj3); + assertSame(cont.get(2), proxyObj3Weak1); + } + + /** Tests List.toArray(), List.toArray(Object[] a) + */ + @Test public void toArray() throws Exception + { + logger.log(Level.INFO, "Testing List.toArray(), List.toArray(Object[] a)"); + InterfaceContainer cont= new InterfaceContainer(); + + cont.addAll(list1); + Object[] ar= cont.toArray(); + Object[] arOrig= list1.toArray(); + assertEquals(ar.length, arOrig.length); + assertArrayEquals(ar, arOrig); + + XWeak[] arWeak= new XWeak[3]; + XWeak[] arWeak2= (XWeak[])cont.toArray(arWeak); + assertEquals(ar.length, arWeak2.length); + assertArrayEquals(ar, arWeak2); + } + + @Test public void Iterator_next() throws Exception + { + logger.log(Level.INFO, "Testing InterfaceContainer.iterator, Iterator.next()"); + InterfaceContainer cont= new InterfaceContainer(); + + cont.addAll(list1); + Iterator it= cont.iterator(); + assertSame(it.next(), list1.get(0)); + assertSame(it.next(), list1.get(1)); + assertSame(it.next(), list1.get(2)); + + try { + it.next(); + fail("NoSuchElementException expected"); + } catch (NoSuchElementException noSuchElementException) { + logger.log(Level.FINE, "NoSuchElementException caught"); + } + } + + @Test public void Iterator_hasNext() throws Exception + { + logger.log(Level.INFO, "Testing, Iterator.next()"); + InterfaceContainer cont= new InterfaceContainer(); + + Iterator it= cont.iterator(); + assertFalse(it.hasNext()); + + cont.addAll(list1); + it= cont.iterator(); + assertTrue(it.hasNext()); + + it.next(); + assertTrue(it.hasNext()); + + it.next(); + assertTrue(it.hasNext()); + + it.next(); + assertFalse(it.hasNext()); + } + + @Test public void Iterator_remove() throws Exception + { + logger.log(Level.INFO, "Testing, Iterator.remove()"); + InterfaceContainer cont= new InterfaceContainer(); + + Iterator it= cont.iterator(); + try { + it.remove(); + fail("IllegalStateException expected"); + } catch (IllegalStateException illegalStateException) { + logger.log(Level.FINE, "IllegalStateException caught"); + } + + cont.add(obj1); + it= cont.iterator(); + it.next(); + it.remove(); + assertTrue(cont.isEmpty()); + try { + it.remove(); + fail("IllegalStateException expected"); + } catch (IllegalStateException illegalStateException) { + logger.log(Level.FINE, "IllegalStateException caught"); + } + + cont.clear(); + cont.addAll(list1); + it= cont.iterator(); + while (it.hasNext()) + { + it.next(); + it.remove(); + } + assertTrue(cont.isEmpty()); + + // 2 iterators, remove must not impair the other iterator + cont.clear(); + cont.addAll(list1); + int size= cont.size(); + it= cont.iterator(); + Iterator it2= cont.iterator(); + while (it.hasNext()) + { + it.next(); + it.remove(); + } + for( int c= 0; c < size; c++) + it2.next(); + assertEquals(cont.size(), 0); + } + + @Test public void ListIterator_next() throws Exception + { + logger.log(Level.INFO, "Testing InterfaceContainer.listIterator, ListIterator.next()"); + InterfaceContainer cont= new InterfaceContainer(); + + cont.addAll(list1); + Iterator it= cont.listIterator(); + assertSame(it.next(), list1.get(0)); + assertSame(it.next(), list1.get(1)); + assertSame(it.next(), list1.get(2)); + try { + it.next(); + fail("NoSuchElementException expected"); + } catch (NoSuchElementException noSuchElementException) { + logger.log(Level.FINE, "NoSuchElementException caught"); + } + } + + @Test public void ListIterator_hasNext() throws Exception + { + logger.log(Level.INFO, "Testing ListIterator.hasNext()"); + InterfaceContainer cont= new InterfaceContainer(); + + Iterator it= cont.listIterator(); + assertFalse(it.hasNext()); + + cont.addAll(list1); + it= cont.listIterator(); + assertTrue(it.hasNext()); + it.next(); + assertTrue(it.hasNext()); + it.next(); + assertTrue(it.hasNext()); + it.next(); + assertFalse(it.hasNext()); + } + + @Test public void ListIterator_remove() throws Exception + { + logger.log(Level.INFO, "Testing ListIterator.remove()"); + InterfaceContainer cont= new InterfaceContainer(); + + ListIterator it= cont.listIterator(); + try { + it.remove(); + fail("IllegalStateException expected"); + } catch (IllegalStateException illegalStateException) { + logger.log(Level.FINE, "IllegalStateException caught"); + } + + cont.add(obj1); + it= cont.listIterator(); + it.next(); + it.remove(); + assertTrue(cont.isEmpty()); + try { + it.remove(); + fail("IllegalStateException expected"); + } catch (IllegalStateException illegalStateException) { + logger.log(Level.FINE, "IllegalStateException caught"); + } + + cont.clear(); + cont.addAll(list1); + it= cont.listIterator(); + while (it.hasNext()) + { + it.next(); + it.remove(); + } + assertTrue(cont.isEmpty()); + + // 2 iterators, remove must not impair the other iterator + cont.clear(); + cont.addAll(list1); + int size= cont.size(); + it= cont.listIterator(); + Iterator it2= cont.listIterator(); + while (it.hasNext()) + { + it.next(); + it.remove(); + } + for( int c= 0; c < size; c++) + it2.next(); + assertEquals(cont.size(), 0); + } + + @Test public void ListIterator_hasPrevious() throws Exception + { + logger.log(Level.INFO, "Testing ListIterator.hasPrevious()"); + InterfaceContainer cont= new InterfaceContainer(); + + ListIterator it= cont.listIterator(); + assertFalse(it.hasPrevious()); + cont.addAll(list1); + it= cont.listIterator(); + while (it.hasNext()) + { + it.next(); + assertTrue(it.hasPrevious()); + } + } + + @Test public void ListIterator_previous() throws Exception + { + logger.log(Level.INFO, "Testing ListIterator.previous()"); + InterfaceContainer cont= new InterfaceContainer(); + + cont.addAll(list1); + // go to the end of our list and list1 + ListIterator it= cont.listIterator(); + while (it.hasNext()) { + it.next(); + } + ListIterator it_list1= list1.listIterator(); + while (it_list1.hasNext()) { + it_list1.next(); + } + + while (it.hasPrevious()) + { + assertSame(it.previous(), it_list1.previous()); + } + try { + it.previous(); + fail("NoSuchElementException expected"); + } catch (NoSuchElementException noSuchElementException) { + logger.log(Level.FINE, "NoSuchElementException caught"); + } + } + + @Test public void ListIterator_nextIndex() throws Exception + { + logger.log(Level.INFO, "Testing ListIterator.nextIndex()"); + InterfaceContainer cont= new InterfaceContainer(); + + ListIterator it; + cont.addAll(list1); + it= cont.listIterator(); + assertEquals(it.nextIndex(), 0); + it.next(); + assertEquals(it.nextIndex(), 1); + it.next(); + assertEquals(it.nextIndex(), 2); + } + + @Test public void ListIterator_previousIndex() throws Exception + { + logger.log(Level.INFO, "Testing ListIterator.previousIndex()"); + InterfaceContainer cont= new InterfaceContainer(); + + ListIterator it; + cont.addAll(list1); + it= cont.listIterator(); + while (it.hasNext()) { + it.next(); + } + + assertEquals(it.previousIndex(), 2); + it.previous(); + assertEquals(it.previousIndex(), 1); + it.previous(); + assertEquals(it.previousIndex(), 0); + it.previous(); + } + + @Test public void ListIterator_add() throws Exception + { + logger.log(Level.INFO, "Testing ListIterator.add()"); + InterfaceContainer cont= new InterfaceContainer(); + + ListIterator it= cont.listIterator(); + it.add(obj1); + assertEquals(cont.size(), 1); + it.add(obj2); + assertEquals(cont.size(), 2); + it.add(obj3); + assertSame(it.previous(), obj3); + assertSame(it.previous(), obj2); + assertSame(it.previous(), obj1); + } + + @Test public void disposeAndClear() throws Exception + { + logger.log(Level.INFO, "Testing InterfaceContainer.disposeAndClear"); + InterfaceContainer cont= new InterfaceContainer(10); + + cont.add(obj1); + cont.add(obj2); + cont.add(obj3); + cont.add(proxyObj1Weak1); + cont.add(proxyObj3TypeProv); + logger.log(Level.FINE, "Two proxies are called. Check the output:"); + cont.disposeAndClear(new com.sun.star.lang.EventObject()); + assertEquals(obj1.nDisposingCalled, 1); + assertEquals(obj2.nDisposingCalled, 1); + assertEquals(obj3.nDisposingCalled, 1); + } +} diff --git a/javaunohelper/test/com/sun/star/lib/uno/helper/MultiTypeInterfaceContainer_Test.java b/javaunohelper/test/com/sun/star/lib/uno/helper/MultiTypeInterfaceContainer_Test.java new file mode 100644 index 000000000..c483a0431 --- /dev/null +++ b/javaunohelper/test/com/sun/star/lib/uno/helper/MultiTypeInterfaceContainer_Test.java @@ -0,0 +1,256 @@ +/* + * 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.lib.uno.helper; + +import com.sun.star.lang.XSingleComponentFactory; +import com.sun.star.lang.XTypeProvider; + +import com.sun.star.uno.XWeak; +import com.sun.star.uno.Type; +import com.sun.star.uno.XInterface; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import org.junit.Before; +import org.junit.Test; + +public class MultiTypeInterfaceContainer_Test +{ + private static final Logger logger = Logger.getLogger(MultiTypeInterfaceContainer_Test.class.getName()); + /** Creates a new instance of InterfaceContainerTest */ + AWeakBase obj1,obj2,obj3,obj4; + Object proxyObj1Weak1; + Object proxyObj3Weak1; + Object proxyObj3Weak2; + Object proxyObj3TypeProv; + Object proxyObj2TypeProv; + //contains original objects + List<Object> list1; + //contains original objects + proxies + List<Object> list2; + //contains original object + proxies + null value + List<Object> list3; + + /** Class variables are initialized before each Test method */ + @Before public void setUp() throws Exception + { + obj1= new AWeakBase(); + obj2= new AWeakBase(); + obj3= new AWeakBase(); + obj4= new AWeakBase(); + + proxyObj1Weak1= ProxyProvider.createProxy(obj1, XWeak.class); + proxyObj3Weak1= ProxyProvider.createProxy(obj3, XWeak.class); + proxyObj3Weak2= ProxyProvider.createProxy(obj3, XWeak.class); + assertNotNull(proxyObj1Weak1); + assertNotNull(proxyObj3Weak1); + assertNotNull(proxyObj3Weak2); + + proxyObj2TypeProv= ProxyProvider.createProxy(obj2, XTypeProvider.class); + proxyObj3TypeProv= ProxyProvider.createProxy(obj3, XTypeProvider.class); + assertNotNull(proxyObj2TypeProv); + assertNotNull(proxyObj3TypeProv); + + list1= new ArrayList<Object>(); + list1.add(obj1); + list1.add(obj2); + list1.add(obj3); + + list2= new ArrayList<Object>(); + list2.add(obj1); + list2.add(proxyObj2TypeProv); + list2.add(proxyObj3TypeProv); + + list3= new ArrayList<Object>(); + list3.add(obj1); + list3.add(null); + list3.add(proxyObj2TypeProv); + list3.add(proxyObj3Weak1); + } + + @Test public void addInterface() throws Exception + { + logger.log(Level.INFO, "Testing MultiTypeInterfaceContainer.addInterface"); + MultiTypeInterfaceContainer cont= new MultiTypeInterfaceContainer(); + + int ci= 0; + ci= cont.addInterface(new Type(XInterface.class), obj1); + ci= cont.addInterface(new Type(XInterface.class), obj2); + ci= cont.addInterface(new Type(XInterface.class), obj3); + assertEquals(ci, 3); + + ci= cont.addInterface(new Type(XWeak.class), obj1); + ci= cont.addInterface(new Type(XWeak.class), obj2); + assertEquals(ci, 2); + + ci= cont.addInterface(null,obj1); + assertEquals(ci, 1); + + ci= cont.addInterface(new Type(XTypeProvider.class), null); + assertEquals(ci, 0); + + cont= new MultiTypeInterfaceContainer(); + AWeakBase[] arObj= new AWeakBase[100]; + for (int c= 0; c < 100; c++) + { + arObj[c]= new AWeakBase(); + ci= cont.addInterface(new Type(XInterface.class), arObj[c]); + } + Type[] arT= cont.getContainedTypes(); + for (int c=0; c < 100; c++) + { + ci= cont.removeInterface(new Type(XInterface.class), arObj[c]); + assertEquals(ci, 100 -c -1); + } + } + + @Test public void getContainedTypes() throws Exception + { + logger.log(Level.INFO, "Testing MultiTypeInterfaceContainer.getContainedTypes"); + MultiTypeInterfaceContainer cont= new MultiTypeInterfaceContainer(); + + cont.addInterface(new Type(XInterface.class), obj1); + cont.addInterface(new Type(XWeak.class), obj1); + cont.addInterface(null, obj1); + cont.addInterface(new Type(XTypeProvider.class), null); + Object aObj= new Object(); + cont.addInterface(aObj, obj1); + cont.addInterface(XSingleComponentFactory.class, obj1); + Type[] types= cont.getContainedTypes(); + // 3 types and no XTypeProvider + assertEquals(types.length, 5); + for (int c= 0; c < types.length; c++) + { + boolean result= false; + if (types[c] == null) + result= true; + else if (types[c].equals(new Type(XTypeProvider.class))) + result= false; + else if (types[c].equals(new Type(XInterface.class))) + result= true; + else if (types[c].equals(new Type(XWeak.class))) + result= true; + else if (types[c].equals(new Type())) + result= true; + else if (types[c].equals(new Type( aObj.getClass()))) + result= true; + else if (types[c].equals(new Type(XSingleComponentFactory.class))) + result= true; + assertTrue(result); + } + } + + @Test public void getContainer() throws Exception + { + logger.log(Level.INFO, "Testing MultiTypeInterfaceContainer.getContainedTypes"); + MultiTypeInterfaceContainer cont= new MultiTypeInterfaceContainer(); + + cont.addInterface(new Type(XInterface.class), obj1); + cont.addInterface(new Type(XInterface.class), obj2); + cont.addInterface(new Type(XInterface.class), obj3); + cont.addInterface(new Type(XWeak.class), obj1); + cont.addInterface(new Type(XWeak.class), obj2); + cont.addInterface(null, obj1); + cont.addInterface(new Type(XTypeProvider.class), null); + + InterfaceContainer icont= null; + icont= cont.getContainer( new Type(XTypeProvider.class)); + assertEquals(icont.size(), 0); + icont= cont.getContainer(new Type(XWeak.class)); + assertEquals(icont.size(), 2); + icont= cont.getContainer(null); + assertEquals(icont.size(), 1); + } + + @Test public void removeInterface() throws Exception + { + logger.log(Level.INFO, "Testing MultiTypeInterfaceContainer.removeInterface"); + MultiTypeInterfaceContainer cont= new MultiTypeInterfaceContainer(); + + int count= 0; + count= cont.removeInterface( new Type(XTypeProvider.class), obj1); + assertEquals(count, 0); + count= cont.removeInterface( new Type(XTypeProvider.class), null); + assertEquals(count, 0); + count= cont.removeInterface(null, obj2); + assertEquals(count, 0); + + cont.addInterface(new Type(XInterface.class), obj1); + cont.addInterface(null, obj1); + count= cont.removeInterface(null, obj2); + // count must still be 1 + assertEquals(count, 1); + count= cont.removeInterface(null, obj1); + assertEquals(count, 0); + count= cont.removeInterface(new Type(XInterface.class), obj1); + assertEquals(count, 0); + } + + @Test public void clear() throws Exception + { + logger.log(Level.INFO, "Testing MultiTypeInterfaceContainer.clear"); + MultiTypeInterfaceContainer cont= new MultiTypeInterfaceContainer(); + + cont.clear(); + Type[] types= cont.getContainedTypes(); + assertEquals(types.length, 0); + cont.addInterface(new Type(XInterface.class), obj1); + cont.addInterface(new Type(XInterface.class), obj2); + cont.addInterface(new Type(XInterface.class), obj3); + cont.addInterface(new Type(XWeak.class), obj1); + cont.addInterface(new Type(XWeak.class), obj2); + cont.addInterface(null, obj1); + cont.addInterface(new Type(XTypeProvider.class), null); + types= cont.getContainedTypes(); + assertEquals(types.length, 3); + cont.clear(); + types= cont.getContainedTypes(); + assertEquals(types.length, 0); + } + + @Test public void disposeAndClear() throws Exception + { + logger.log(Level.INFO, "Testing MultiTypeInterfaceContainer.disposeAndClear"); + MultiTypeInterfaceContainer cont= new MultiTypeInterfaceContainer(); + + obj1.nDisposingCalled= 0; + obj2.nDisposingCalled= 0; + obj3.nDisposingCalled= 0; + cont.addInterface(new Type(XInterface.class), null); + cont.addInterface(new Type(XInterface.class), obj1); + cont.addInterface(new Type(XInterface.class), obj2); + cont.addInterface(new Type(XInterface.class), obj3); + cont.addInterface(new Type(XWeak.class),obj1); + cont.addInterface(new Type(XWeak.class), obj2); + cont.addInterface(new Type(XTypeProvider.class), obj1); + cont.disposeAndClear(new com.sun.star.lang.EventObject("blabla")); + + assertEquals(obj1.nDisposingCalled, 3); + assertEquals(obj2.nDisposingCalled, 2); + assertEquals(obj3.nDisposingCalled, 1); + Type[] types= cont.getContainedTypes(); + assertEquals(types.length, 0); + } +}
\ No newline at end of file diff --git a/javaunohelper/test/com/sun/star/lib/uno/helper/PropertySet_Test.java b/javaunohelper/test/com/sun/star/lib/uno/helper/PropertySet_Test.java new file mode 100644 index 000000000..41149ba61 --- /dev/null +++ b/javaunohelper/test/com/sun/star/lib/uno/helper/PropertySet_Test.java @@ -0,0 +1,1666 @@ +/* + * 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.lib.uno.helper; + +import com.sun.star.lang.EventObject; +import com.sun.star.lang.DisposedException; +import com.sun.star.uno.Type; +import com.sun.star.uno.TypeClass; +import com.sun.star.uno.XInterface; +import com.sun.star.uno.Any; +import com.sun.star.uno.XWeak; +import com.sun.star.beans.UnknownPropertyException; +import com.sun.star.beans.Property; +import com.sun.star.beans.PropertyAttribute; +import com.sun.star.beans.XPropertyChangeListener; +import com.sun.star.beans.PropertyVetoException; +import com.sun.star.beans.PropertyChangeEvent; +import com.sun.star.beans.XVetoableChangeListener; +import com.sun.star.beans.XPropertySetInfo; +import com.sun.star.beans.XPropertiesChangeListener; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import org.junit.Test; + +public class PropertySet_Test +{ + + private static final Logger logger = Logger.getLogger(PropertySet_Test.class.getName()); + + @Test public void convertPropertyValue() throws Exception + { + logger.log(Level.INFO, "PropertySet.convertPropertyValue"); + TestClass cl= new TestClass(); + cl.test_convertPropertyValue(); + } + + @Test public void setPropertyValueNoBroadcast() throws Exception + { + logger.log(Level.INFO, "PropertySet.setValueNoBroadcast"); + TestClass cl= new TestClass(); + cl.test_setPropertyValueNoBroadcast(); + } + + @Test public void setPropertyValue() throws Exception + { + logger.log(Level.INFO, "PropertySet.setPropertyValue"); + TestClass cl= new TestClass(); + cl.resetPropertyMembers(); + Object value; + Object ret; + + value= Boolean.TRUE; + cl.setPropertyValue("PropBoolA", value); + assertEquals(cl.getPropertyValue("PropBoolA"), value); + + value= new Character('A'); + cl.setPropertyValue("PropCharA",value); + assertEquals(cl.getPropertyValue("PropCharA"), value); + + value= Byte.valueOf((byte) 111); + cl.setPropertyValue("PropByteA",value); + assertEquals(cl.getPropertyValue("PropByteA"), value); + + value= Short.valueOf((short)112); + cl.setPropertyValue("PropShortA", value); + assertEquals(cl.getPropertyValue("PropShortA"), value); + + value= Integer.valueOf(113); + cl.setPropertyValue("PropIntA", value); + assertEquals(cl.getPropertyValue("PropIntA"), value); + + value= Long.valueOf(115); + cl.setPropertyValue("PropLongA", value); + assertEquals(cl.getPropertyValue("PropLongA"), value); + + value= new Float(3.14); + cl.setPropertyValue("PropFloatA", value); + assertEquals(cl.getPropertyValue("PropFloatA"), value); + + value= new Double(3.145); + cl.setPropertyValue("PropDoubleA",value); + assertEquals(cl.getPropertyValue("PropDoubleA"), value); + + value= "string"; + cl.setPropertyValue("PropStringA",value); + assertEquals(cl.getPropertyValue("PropStringA"), value); + + value= new ComponentBase(); + cl.setPropertyValue("PropXInterfaceA",value); + assertEquals(cl.getPropertyValue("PropXInterfaceA"), value); + + value= new ComponentBase(); + cl.setPropertyValue("PropXWeakA",value); + assertEquals(cl.getPropertyValue("PropXWeakA"), value); + + value = com.sun.star.beans.PropertyState.AMBIGUOUS_VALUE; + cl.setPropertyValue("PropEnum",value); + assertSame(cl.getPropertyValue("PropEnum"), value); + + value= new byte[]{1,2,3}; + cl.setPropertyValue("PropArrayByteA", value); + assertEquals(cl.getPropertyValue("PropArrayByteA"), value); + + value= new Type(String.class); + cl.setPropertyValue("PropTypeA", value); + assertEquals(cl.getPropertyValue("PropTypeA"), value); + + // test protected,package,private members + value= Boolean.TRUE; + cl.setPropertyValue("PropBoolB", value); + assertEquals(cl.getPropertyValue("PropBoolB"), value); + + cl.setPropertyValue("PropBoolC", value); + assertEquals(cl.getPropertyValue("PropBoolC"), value); + + try { + cl.setPropertyValue("PropBoolD", value); + fail("com.sun.star.lang.WrappedTargetException expected"); + } catch(com.sun.star.lang.WrappedTargetException e) { + logger.log(Level.FINE, "com.sun.star.lang.WrappedTargetException caught"); + } + + cl.resetPropertyMembers(); + + value= Boolean.TRUE; + cl.setPropertyValue("PropObjectA", value); + assertEquals(cl.getPropertyValue("PropObjectA"), value); + + value= new Character('A'); + cl.setPropertyValue("PropObjectA",value); + assertEquals(cl.getPropertyValue("PropObjectA"), value); + + value= Byte.valueOf((byte) 111); + cl.setPropertyValue("PropObjectA",value); + assertEquals(cl.getPropertyValue("PropObjectA"), value); + + value= Short.valueOf((short)112); + cl.setPropertyValue("PropObjectA", value); + assertEquals(cl.getPropertyValue("PropObjectA"), value); + + value= Integer.valueOf(113); + cl.setPropertyValue("PropObjectA", value); + assertEquals(cl.getPropertyValue("PropObjectA"), value); + + value= Long.valueOf(115); + cl.setPropertyValue("PropObjectA", value); + assertEquals(cl.getPropertyValue("PropObjectA"), value); + + value= new Float(3.14); + cl.setPropertyValue("PropObjectA", value); + assertEquals(cl.getPropertyValue("PropObjectA"), value); + + value= new Double(3.145); + cl.setPropertyValue("PropObjectA",value); + assertEquals(cl.getPropertyValue("PropObjectA"), value); + + value= "string"; + cl.setPropertyValue("PropObjectA",value); + assertEquals(cl.getPropertyValue("PropObjectA"), value); + + value= new ComponentBase(); + cl.setPropertyValue("PropObjectA",value); + assertEquals(cl.getPropertyValue("PropObjectA"), value); + + value= new ComponentBase(); + cl.setPropertyValue("PropObjectA",value); + assertEquals(cl.getPropertyValue("PropObjectA"), value); + + value= new byte[]{1,2,3}; + cl.setPropertyValue("PropObjectA", value); + assertEquals(cl.getPropertyValue("PropObjectA"), value); + + value= new Type(String.class); + cl.setPropertyValue("PropObjectA", value); + assertEquals(cl.getPropertyValue("PropObjectA"), value); + + cl.setPropertyValue("PropObjectA", new Any( new Type(byte.class), Byte.valueOf((byte)1))); + assertEquals(((Byte) cl.getPropertyValue("PropObjectA")).byteValue(), 1); + + cl.resetPropertyMembers(); + + value= Boolean.TRUE; + cl.setPropertyValue("PropAnyA", value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new Character('A'); + cl.setPropertyValue("PropAnyA",value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= Byte.valueOf((byte) 111); + cl.setPropertyValue("PropAnyA",value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= Short.valueOf((short)112); + cl.setPropertyValue("PropAnyA", value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= Integer.valueOf(113); + cl.setPropertyValue("PropAnyA", value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= Long.valueOf(115); + cl.setPropertyValue("PropAnyA", value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new Float(3.14); + cl.setPropertyValue("PropAnyA", value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new Double(3.145); + cl.setPropertyValue("PropAnyA",value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= "string"; + cl.setPropertyValue("PropAnyA",value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new ComponentBase(); + cl.setPropertyValue("PropAnyA",value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new ComponentBase(); + cl.setPropertyValue("PropAnyA",value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new byte[]{1,2,3}; + cl.setPropertyValue("PropAnyA", value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new Type(String.class); + cl.setPropertyValue("PropAnyA", value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + cl.resetPropertyMembers(); + + value= new Any(new Type(boolean.class), Boolean.TRUE); + cl.setPropertyValue("PropBoolA", value); + ret= cl.getPropertyValue("PropBoolA"); + assertTrue(ret instanceof Boolean); + assertTrue(util.anyEquals(value, ret)); + + value= new Any (new Type(char.class), new Character('A')); + cl.setPropertyValue("PropCharA",value); + ret= cl.getPropertyValue("PropCharA"); + assertTrue(ret instanceof Character); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(byte.class), Byte.valueOf((byte) 111)); + cl.setPropertyValue("PropByteA",value); + ret= cl.getPropertyValue("PropByteA"); + assertTrue(ret instanceof Byte); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(short.class), Short.valueOf((short)112)); + cl.setPropertyValue("PropShortA", value); + ret= cl.getPropertyValue("PropShortA"); + assertTrue(ret instanceof Short); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(int.class), Integer.valueOf(113)); + cl.setPropertyValue("PropIntA", value); + ret= cl.getPropertyValue("PropIntA"); + assertTrue(ret instanceof Integer); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(long.class), Long.valueOf(115)); + cl.setPropertyValue("PropLongA", value); + ret= cl.getPropertyValue("PropLongA"); + assertTrue(ret instanceof Long); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(float.class), new Float(3.14)); + cl.setPropertyValue("PropFloatA", value); + ret= cl.getPropertyValue("PropFloatA"); + assertTrue(ret instanceof Float); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(double.class),new Double(3.145)); + cl.setPropertyValue("PropDoubleA",value); + ret= cl.getPropertyValue("PropDoubleA"); + assertTrue(ret instanceof Double); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(String.class), "string"); + cl.setPropertyValue("PropStringA",value); + ret= cl.getPropertyValue("PropStringA"); + assertTrue(ret instanceof String); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(ComponentBase.class), new ComponentBase()); + cl.setPropertyValue("PropXInterfaceA",value); + ret= cl.getPropertyValue("PropXInterfaceA"); + assertTrue(ret instanceof ComponentBase); + assertTrue(util.anyEquals(value, ret)); + + value= new Any( new Type(ComponentBase.class), new ComponentBase()); + cl.setPropertyValue("PropXWeakA",value); + ret= cl.getPropertyValue("PropXWeakA"); + assertTrue(ret instanceof ComponentBase); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(byte[].class), new byte[]{1,2,3}); + cl.setPropertyValue("PropArrayByteA", value); + ret= cl.getPropertyValue("PropArrayByteA"); + assertTrue(ret instanceof byte[]); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(Type.class), new Type(String.class)); + cl.setPropertyValue("PropTypeA", value); + ret= cl.getPropertyValue("PropTypeA"); + assertTrue(ret instanceof Type); + assertTrue(util.anyEquals(value, ret)); + + cl.resetPropertyMembers(); + + value= new Any(new Type(boolean.class), Boolean.TRUE); + cl.setPropertyValue("PropAnyA", value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new Any (new Type(char.class), new Character('A')); + cl.setPropertyValue("PropAnyA",value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(byte.class), Byte.valueOf((byte) 111)); + cl.setPropertyValue("PropAnyA",value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(short.class), Short.valueOf((short)112)); + cl.setPropertyValue("PropAnyA", value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(int.class), Integer.valueOf(113)); + cl.setPropertyValue("PropAnyA", value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(long.class), Long.valueOf(115)); + cl.setPropertyValue("PropAnyA", value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(float.class), new Float(3.14)); + cl.setPropertyValue("PropAnyA", value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(double.class),new Double(3.145)); + cl.setPropertyValue("PropAnyA",value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(String.class), "string"); + cl.setPropertyValue("PropAnyA",value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(ComponentBase.class), new ComponentBase()); + cl.setPropertyValue("PropAnyA",value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new Any( new Type(ComponentBase.class), new ComponentBase()); + cl.setPropertyValue("PropAnyA",value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(byte[].class), new byte[]{1,2,3}); + cl.setPropertyValue("PropAnyA", value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(Type.class), new Type(String.class)); + cl.setPropertyValue("PropAnyA", value); + ret= cl.getPropertyValue("PropAnyA"); + assertTrue(ret instanceof Any); + assertTrue(util.anyEquals(value, ret)); + + cl.resetPropertyMembers(); + + value= Boolean.TRUE; + cl.setPropertyValue("PropBoolClass", value); + assertEquals(cl.getPropertyValue("PropBoolClass"), value); + + value= new Character('A'); + cl.setPropertyValue("PropCharClass",value); + assertEquals(cl.getPropertyValue("PropCharClass"), value); + + value= Byte.valueOf((byte) 111); + cl.setPropertyValue("PropByteClass",value); + assertEquals(cl.getPropertyValue("PropByteClass"), value); + + value= Short.valueOf((short)112); + cl.setPropertyValue("PropShortClass", value); + assertEquals(cl.getPropertyValue("PropShortClass"), value); + + value= Integer.valueOf(113); + cl.setPropertyValue("PropIntClass", value); + assertEquals(cl.getPropertyValue("PropIntClass"), value); + + value= Long.valueOf(115); + cl.setPropertyValue("PropLongClass", value); + assertEquals(cl.getPropertyValue("PropLongClass"), value); + + value= new Float(3.14); + cl.setPropertyValue("PropFloatClass", value); + assertEquals(cl.getPropertyValue("PropFloatClass"), value); + + value= new Double(3.145); + cl.setPropertyValue("PropDoubleClass",value); + assertEquals(cl.getPropertyValue("PropDoubleClass"), value); + + cl.resetPropertyMembers(); + + cl.resetPropertyMembers(); + + value= new Any(new Type(boolean.class), Boolean.TRUE); + cl.setPropertyValue("PropBoolClass", value); + ret= cl.getPropertyValue("PropBoolClass"); + assertTrue(ret instanceof Boolean); + assertTrue(util.anyEquals(value, ret)); + + value= new Any (new Type(char.class), new Character('A')); + cl.setPropertyValue("PropCharClass",value); + ret= cl.getPropertyValue("PropCharClass"); + assertTrue(ret instanceof Character); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(byte.class), Byte.valueOf((byte) 111)); + cl.setPropertyValue("PropByteClass",value); + ret= cl.getPropertyValue("PropByteClass"); + assertTrue(ret instanceof Byte); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(short.class), Short.valueOf((short)112)); + cl.setPropertyValue("PropShortClass", value); + ret= cl.getPropertyValue("PropShortClass"); + assertTrue(ret instanceof Short); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(int.class), Integer.valueOf(113)); + cl.setPropertyValue("PropIntClass", value); + ret= cl.getPropertyValue("PropIntClass"); + assertTrue(ret instanceof Integer); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(long.class), Long.valueOf(115)); + cl.setPropertyValue("PropLongClass", value); + ret= cl.getPropertyValue("PropLongClass"); + assertTrue(ret instanceof Long); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(float.class), new Float(3.14)); + cl.setPropertyValue("PropFloatClass", value); + ret= cl.getPropertyValue("PropFloatClass"); + assertTrue(ret instanceof Float); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(double.class),new Double(3.145)); + cl.setPropertyValue("PropDoubleClass",value); + ret= cl.getPropertyValue("PropDoubleClass"); + assertTrue(ret instanceof Double); + assertTrue(util.anyEquals(value, ret)); + + value= new Any(new Type(String.class), "string"); + + // PropertyAttribute.READONLY + cl.propBoolA.Attributes= PropertyAttribute.READONLY; + try { + cl.setPropertyValue("PropBoolA", Boolean.TRUE); + fail("com.sun.star.beans.PropertyVetoException expected"); + } catch (com.sun.star.beans.PropertyVetoException e) { + logger.log(Level.FINE, "com.sun.star.beans.PropertyVetoException caught"); + } + cl.propBoolA.Attributes= 0; + + // MAYBEVOID + cl.resetPropertyMembers(); + // first MAYBEVOID not set + + //primitive members: must not work + + cl.boolPropA= false; + try { + cl.setPropertyValue("PropBoolA", null); + fail("com.sun.star.lang.IllegalArgumentException expected"); + } catch (com.sun.star.lang.IllegalArgumentException e) { + logger.log(Level.FINE, "com.sun.star.lang.IllegalArgumentException caught"); + } + + try { + cl.setPropertyValue("PropBoolA", new Any(new Type(boolean.class), null)); + fail("com.sun.star.lang.IllegalArgumentException expected"); + } catch (com.sun.star.lang.IllegalArgumentException e) { + logger.log(Level.FINE, "com.sun.star.lang.IllegalArgumentException caught"); + } + + cl.propBoolA.Attributes= PropertyAttribute.MAYBEVOID; + try { + cl.setPropertyValue("PropBoolA", null); + fail("com.sun.star.lang.IllegalArgumentException expected"); + } catch (com.sun.star.lang.IllegalArgumentException e) { + logger.log(Level.FINE, "com.sun.star.lang.IllegalArgumentException caught"); + } + + cl.propBoolA.Attributes= 0; + + cl.propBoolClass.Attributes= PropertyAttribute.MAYBEVOID; + cl.boolClassProp= null; + cl.setPropertyValue("PropBoolClass", null); + assertNull(cl.boolClassProp); + + // the returned value must be a void any + Object objAny= cl.getPropertyValue("PropBoolClass"); + assertTrue(util.isVoidAny( objAny)); + + cl.boolClassProp= Boolean.TRUE; + cl.setPropertyValue("PropBoolClass", null); + assertNull(cl.boolClassProp); + + cl.boolClassProp= Boolean.FALSE; + cl.setPropertyValue("PropBoolClass", new Any(new Type(boolean.class),null)); + assertNull(cl.boolClassProp); + + cl.propXWeakA.Attributes= PropertyAttribute.MAYBEVOID; + cl.setPropertyValue("PropXWeakA", null); + assertTrue(util.isVoidAny(cl.getPropertyValue("PropXWeakA"))); + + cl.propXWeakA.Attributes= 0; + + cl.anyPropA= null; + try { + cl.setPropertyValue("PropAnyA", null); + fail("com.sun.star.lang.IllegalArgumentException expected"); + } catch (com.sun.star.lang.IllegalArgumentException e) { + logger.log(Level.FINE, "com.sun.star.lang.IllegalArgumentException caught"); + } + cl.anyPropA= null; + cl.propAnyA.Attributes= PropertyAttribute.MAYBEVOID; + + new Type(Object.class); + cl.setPropertyValue("PropAnyA", null); + assertEquals(cl.anyPropA.getType(), new Type(void.class)); + assertNull(cl.anyPropA.getObject()); + + cl.anyPropA= new Any(new Type(byte.class),Byte.valueOf((byte) 111)); + cl.setPropertyValue("PropAnyA", null); + assertEquals(cl.anyPropA.getType(), new Type(byte.class)); + assertNull(cl.anyPropA.getObject()); + + cl.anyPropA= null; + try { + cl.setPropertyValue("PropAnyA", new Object()); + fail("com.sun.star.lang.IllegalArgumentException expected"); + }catch (com.sun.star.lang.IllegalArgumentException e) { + logger.log(Level.FINE, "com.sun.star.lang.IllegalArgumentException caught"); + } + + cl.propObjectA.Attributes= 0; + try { + cl.setPropertyValue("PropObjectA", null); + fail("com.sun.star.lang.IllegalArgumentException expected"); + } catch (com.sun.star.lang.IllegalArgumentException e) { + logger.log(Level.FINE, "com.sun.star.lang.IllegalArgumentException caught"); + } + + try { + cl.setPropertyValue("PropObjectA", new Any( new Type(byte.class), null)); + fail("com.sun.star.lang.IllegalArgumentException expected"); + } catch (com.sun.star.lang.IllegalArgumentException e) { + logger.log(Level.FINE, "com.sun.star.lang.IllegalArgumentException caught"); + } + + cl.propObjectA.Attributes= PropertyAttribute.MAYBEVOID; + cl.propObjectA= null; + cl.setPropertyValue("PropObjectA", null); + assertNull(cl.propObjectA); + + cl.propObjectA= null; + cl.setPropertyValue("PropObjectA", new Any( new Type(byte.class), null)); + assertNull(cl.propObjectA); + } + + @Test public void addPropertyChangeListener() throws Exception + { + logger.log(Level.INFO, "PropertySet.addPropertyChangeListener,\n" + + "PropertySet.removePropertChangeListener," + + "PropertySet.addVetoableChangeListener, \n" + + "PropertySet.removeVetoableChangeListener" + + "Notification of listeners"); + TestClass cl= new TestClass(); + Listener li= new Listener(); + + cl.addPropertyChangeListener("PropByteA", li); + Byte val1= Byte.valueOf((byte)115); + cl.setPropertyValue("PropByteA", val1); + assertEquals(li.nChangeCalled, 0); + assertEquals(li.nVetoCalled, 0); + + cl.propByteA.Attributes = PropertyAttribute.BOUND; + cl.addPropertyChangeListener("PropByteA", li); + Byte val2= Byte.valueOf((byte)116); + cl.setPropertyValue("PropByteA", val2); + assertEquals(li.nChangeCalled, 1); + assertEquals(li.nVetoCalled, 0); + assertEquals(li.evt.OldValue, val1); + assertEquals(li.evt.NewValue, val2); + assertSame(li.evt.Source, cl); + + li.reset(); + Listener li2= new Listener(); + cl.addPropertyChangeListener("PropByteA", li2); + Byte val3= Byte.valueOf((byte) 117); + cl.setPropertyValue("PropByteA", val3); + assertEquals(li.nChangeCalled, 1); + assertEquals(li.nVetoCalled, 0); + assertEquals(li2.nChangeCalled, 1); + assertEquals(li2.nVetoCalled, 0); + assertEquals(li.evt.OldValue, val2); + assertEquals(li.evt.NewValue,val3); + assertSame(li.evt.Source, cl); + assertEquals(li2.evt.OldValue, val2); + assertEquals(li2.evt.NewValue, val3); + assertSame(li2.evt.Source, cl); + + li.reset(); + li2.reset(); + Listener li3= new Listener(); + val1= Byte.valueOf((byte)118); + cl.addPropertyChangeListener("", li3); + cl.setPropertyValue("PropByteA", val1); + assertEquals(li.nChangeCalled, 1); + assertEquals(li.nVetoCalled, 0); + assertEquals(li2.nChangeCalled, 1); + assertEquals(li2.nVetoCalled, 0); + assertEquals(li3.nChangeCalled, 1); + assertEquals(li3.nVetoCalled, 0); + assertEquals(li.evt.OldValue, val3); + assertEquals(li.evt.NewValue, val1); + assertSame(li.evt.Source, cl); + assertEquals(li2.evt.OldValue, val3); + assertEquals(li2.evt.NewValue, val1); + assertSame(li2.evt.Source, cl); + assertEquals(li3.evt.OldValue, val3); + assertEquals(li3.evt.NewValue, val1); + assertSame(li3.evt.Source, cl); + + li.reset(); + li2.reset(); + li3.reset(); + cl.removePropertyChangeListener("PropByteA",li); + cl.setPropertyValue("PropByteA", val1); + assertEquals(li.nChangeCalled, 0); + assertEquals(li.nVetoCalled, 0); + assertEquals(li2.nChangeCalled, 1); + assertEquals(li2.nVetoCalled, 0); + assertEquals(li3.nChangeCalled, 1); + assertEquals(li3.nVetoCalled, 0); + + cl.removePropertyChangeListener("PropByteA", li2); + li.reset(); + li2.reset(); + li3.reset(); + cl.setPropertyValue("PropByteA", val1); + assertEquals(li.nChangeCalled, 0); + assertEquals(li.nVetoCalled, 0); + assertEquals(li2.nChangeCalled, 0); + assertEquals(li2.nVetoCalled, 0); + assertEquals(li3.nChangeCalled, 1); + assertEquals(li3.nVetoCalled, 0); + + cl.removePropertyChangeListener("", li3); + li.reset(); + li2.reset(); + li3.reset(); + cl.setPropertyValue("PropByteA", val2); + assertEquals(li.nChangeCalled, 0); + assertEquals(li.nVetoCalled, 0); + assertEquals(li2.nChangeCalled, 0); + assertEquals(li2.nVetoCalled, 0); + assertEquals(li3.nChangeCalled, 0); + assertEquals(li3.nVetoCalled, 0); + + cl.addPropertyChangeListener("PropByteA", li); + cl.addPropertyChangeListener("PropByteA", li2); + cl.addPropertyChangeListener("", li3); + cl.dispose(); + li.reset(); + li2.reset(); + li3.reset(); + try { + cl.setPropertyValue("PropByteA", val2); + fail("DisposedException expected"); + } catch (DisposedException e) { + logger.log(Level.FINE, "DisposedException caught"); + } + + //Vetoable tests + cl= new TestClass(); + li.reset(); + li2.reset(); + li3.reset(); + cl.addVetoableChangeListener("PropByteA", li); + val1= Byte.valueOf((byte)115); + cl.setPropertyValue("PropByteA", val1); + assertEquals(li.nChangeCalled, 0); + assertEquals(li.nVetoCalled, 0); + + cl.propByteA.Attributes = PropertyAttribute.CONSTRAINED; + cl.addVetoableChangeListener("PropByteA", li); + val2= Byte.valueOf((byte)116); + li.reset(); + cl.setPropertyValue("PropByteA", val2); + assertEquals(li.nChangeCalled, 0); + assertEquals(li.nVetoCalled, 1); + assertEquals(li.evt.OldValue, val1); + assertEquals(li.evt.NewValue, val2); + assertSame(li.evt.Source, cl); + + li.reset(); + li2.reset(); + li3.reset(); + cl.addVetoableChangeListener("PropByteA", li2); + val3= Byte.valueOf((byte) 117); + cl.setPropertyValue("PropByteA", val3); + assertEquals(li.nChangeCalled, 0); + assertEquals(li.nVetoCalled, 1); + assertEquals(li2.nChangeCalled, 0); + assertEquals(li2.nVetoCalled, 1); + assertEquals(li.evt.OldValue, val2); + assertEquals(li.evt.NewValue, val3); + assertSame(li.evt.Source, cl); + assertEquals(li2.evt.OldValue, val2); + assertEquals(li2.evt.NewValue, val3); + assertSame(li2.evt.Source, cl); + + li.reset(); + li2.reset(); + li3.reset(); + val1= Byte.valueOf((byte)118); + cl.addVetoableChangeListener("", li3); + cl.setPropertyValue("PropByteA", val1); + assertEquals(li.nChangeCalled, 0); + assertEquals(li.nVetoCalled, 1); + assertEquals(li2.nChangeCalled, 0); + assertEquals(li2.nVetoCalled, 1); + assertEquals(li3.nChangeCalled, 0); + assertEquals(li3.nVetoCalled, 1); + assertEquals(li.evt.OldValue, val3); + assertEquals(li.evt.NewValue, val1); + assertSame(li.evt.Source, cl); + assertEquals(li2.evt.OldValue, val3); + assertEquals(li2.evt.NewValue, val1); + assertSame(li2.evt.Source, cl); + assertEquals(li3.evt.OldValue, val3); + assertEquals(li3.evt.NewValue, val1); + assertSame(li3.evt.Source, cl); + + li.reset(); + li2.reset(); + li3.reset(); + // Test Veto Exception + cl.setPropertyValue("PropByteA", val1); + li.bVeto= true; + try { + cl.setPropertyValue("PropByteA", val2); + fail("PropertyVetoException expected"); + } catch (PropertyVetoException e) { + logger.log(Level.FINE, "PropertyVetoException caught"); + } + assertSame(cl.bytePropA, val1.byteValue()); + li.bVeto= false; + + li.reset(); + li2.reset(); + li3.reset(); + cl.removeVetoableChangeListener("PropByteA",li); + cl.setPropertyValue("PropByteA", val1); + assertEquals(li.nChangeCalled, 0); + assertEquals(li.nVetoCalled, 0); + assertEquals(li2.nChangeCalled, 0); + assertEquals(li2.nVetoCalled, 1); + assertEquals(li3.nChangeCalled, 0); + assertEquals(li3.nVetoCalled, 1); + + cl.removeVetoableChangeListener("PropByteA", li2); + li.reset(); + li2.reset(); + li3.reset(); + cl.setPropertyValue("PropByteA", val1); + assertEquals(li.nChangeCalled, 0); + assertEquals(li.nVetoCalled, 0); + assertEquals(li2.nChangeCalled, 0); + assertEquals(li2.nVetoCalled, 0); + assertEquals(li3.nChangeCalled, 0); + assertEquals(li3.nVetoCalled, 1); + + cl.removeVetoableChangeListener("", li3); + li.reset(); + li2.reset(); + li3.reset(); + cl.setPropertyValue("PropByteA", val2); + assertEquals(li.nChangeCalled, 0); + assertEquals(li.nVetoCalled, 0); + assertEquals(li2.nChangeCalled, 0); + assertEquals(li2.nVetoCalled, 0); + assertEquals(li3.nChangeCalled, 0); + assertEquals(li3.nVetoCalled, 0); + + cl.addVetoableChangeListener("PropByteA", li); + cl.addVetoableChangeListener("PropByteA", li2); + cl.addVetoableChangeListener("", li3); + cl.dispose(); + li.reset(); + li2.reset(); + li3.reset(); + try { + cl.setPropertyValue("PropByteA", val2); + fail("DisposedException expected"); + } catch (DisposedException e) { + logger.log(Level.FINE, "DisposedException caught"); + } + } + + @Test public void getPropertySetInfo() throws Exception + { + logger.log(Level.INFO, "PropertySet.getPropertySetInfo"); + TestClass cl= new TestClass(); + XPropertySetInfo info= cl.getPropertySetInfo(); + Property[] arProps= info.getProperties(); + Property[] arRegProps= cl.getRegisteredProperties(); + assertEquals(arProps.length, arRegProps.length); + + for (int j= 0; j < arProps.length; j++) + { + boolean bFound= false; + for (int k= 0; k < arRegProps.length; k++) + { + if (arProps[j] == arRegProps[k]) + { + bFound= true; + break; + } + } + assertTrue(bFound); + } + + for (int j= 0; j < arRegProps.length; j++) + { + Property prop= info.getPropertyByName(arRegProps[j].Name); + assertSame(prop, arRegProps[j]); + assertTrue(info.hasPropertyByName(arRegProps[j].Name)); + } + } + + @Test public void setFastPropertyValue() throws Exception + { + logger.log(Level.INFO, "PropertySet.setFastPropertyValue"); + TestClass cl= new TestClass(); + cl.setFastPropertyValue(5, Integer.valueOf(111)); + assertEquals(cl.intPropA,111); + try { + cl.setFastPropertyValue(-1, Integer.valueOf(1)); + fail("UnknownPropertyException expected"); + } catch(UnknownPropertyException e) { + logger.log(Level.FINE, "UnknownPropertyException caught"); + } + } + + @Test public void getFastPropertyValue() throws Exception + { + logger.log(Level.INFO, "PropertySet.setFastPropertyValue"); + TestClass cl= new TestClass(); + cl.setFastPropertyValue(5, Integer.valueOf(111)); + Integer aInt= (Integer) cl.getFastPropertyValue(5); + assertEquals(aInt.intValue(), 111); + } + + @Test public void setPropertyValues() throws Exception + { + logger.log(Level.INFO, "PropertySet.setPropertyValues"); + TestClass cl= new TestClass(); + cl.setPropertyValues(new String[0], new Object[0]); + String[] arNames= new String[] {"PropCharA","PropIntClass","PropObjectA"}; + Character aChar= new Character('A'); + Integer aInt= Integer.valueOf(111); + Byte aByte= Byte.valueOf((byte)11); + Object[] values= new Object[]{aChar, aInt, aByte}; + cl.setPropertyValues(arNames, values); + assertEquals(cl.charPropA, 'A'); + assertEquals(cl.intClassProp.intValue(), 111); + assertEquals(((Byte)cl.objectPropA).byteValue(), 11); + + arNames= new String[] {"blabla","PropIntClass","PropObjectA"}; + cl.resetPropertyMembers(); + cl.setPropertyValues(arNames, values); + assertEquals(cl.intClassProp.intValue(), 111); + assertEquals(((Byte)cl.objectPropA).byteValue(), 11); + } + + @Test public void getPropertyValues() throws Exception + { + logger.log(Level.INFO, "PropertySet.getPropertyValues"); + TestClass cl= new TestClass(); + cl.charPropA= 'A'; + cl.intClassProp= Integer.valueOf(111); + cl.objectPropA= Byte.valueOf((byte)11); + Object[] values= cl.getPropertyValues(new String[] {"PropCharA","PropIntClass","PropObjectA"}); + assertEquals(((Character) values[0]).charValue(), 'A'); + assertEquals(((Integer) values[1]).intValue(), 111); + assertEquals(((Byte) values[2]).byteValue(), 11); + } + + // Currently the listeners are always notified if one of properties has changed. + // The property names in the first argument are ignored. + @Test public void addPropertiesChangeListener() throws Exception + { + logger.log(Level.INFO, "PropertySet.addPropertiesChangeListener\n" + + "PropertySet.removePropertiesChangeListener\n" + + "notification of such listeners"); + TestClass cl= new TestClass(); + Listener li1= new Listener(); + + cl.addPropertiesChangeListener(new String[]{"PropCharA"}, li1); + cl.setPropertyValue("PropCharA", new Character('B')); + assertEquals(li1.nPropertiesChange, 0); + + cl.propCharA.Attributes= PropertyAttribute.BOUND; + cl.setPropertyValue("PropCharA", new Character('C')); + assertEquals(li1.nPropertiesChange, 1); + + PropertyChangeEvent evt= li1.arEvt[0]; + assertEquals(evt.PropertyName, "PropCharA"); + assertEquals(((Character)evt.OldValue).charValue(), 'B'); + assertEquals(((Character) evt.NewValue).charValue(), 'C'); + + li1.reset(); + cl.removePropertiesChangeListener(li1); + cl.setPropertyValue("PropCharA", new Character('F')); + assertEquals(li1.nPropertiesChange, 0); + } + + @Test public void firePropertiesChangeEvent() throws Exception + { + logger.log(Level.INFO, "PropertySet.firePropertiesChangeEvent"); + TestClass cl= new TestClass(); + Listener li1= new Listener(); + + cl.intClassProp= Integer.valueOf(111); + cl.charPropA= 'A'; + cl.firePropertiesChangeEvent(new String[]{"PropCharA","PropIntClass"}, li1); + assertEquals(li1.nPropertiesChange, 1); + + PropertyChangeEvent[] arEvt= li1.arEvt; + assertEquals(arEvt[0].PropertyName, "PropCharA"); + assertEquals(((Character) arEvt[0].OldValue).charValue(), 'A'); + assertEquals(((Character) arEvt[0].NewValue).charValue(), 'A'); + assertEquals(arEvt[1].PropertyName, "PropIntClass"); + assertEquals(((Integer) arEvt[1].OldValue).intValue(), 111); + assertEquals(((Integer) arEvt[1].NewValue).intValue(), 111); + } + + @Test public void registerProperty1() throws Exception + { + TestClass2 cl= new TestClass2(); + cl.test_registerProperty1(); + } + + @Test public void registerProperty2() throws Exception + { + TestClass2 cl= new TestClass2(); + cl.test_registerProperty2(); + } +} + +class TestClass extends PropertySet +{ + private static final Logger logger = Logger.getLogger(TestClass.class.getName()); + + public Property propBoolA= new Property("PropBoolA", 1, new Type(Boolean.TYPE), (short)0); + public boolean boolPropA; + public Property propCharA= new Property("PropCharA", 2, new Type(Character.TYPE), (short) 0); + public char charPropA; + public Property propByteA= new Property("PropByteA", 3, new Type(Byte.TYPE), (short) 0); + public byte bytePropA; + public Property propShortA= new Property("PropShortA", 4, new Type(Short.TYPE), (short) 0); + public short shortPropA; + public Property propIntA= new Property("PropIntA", 5, new Type(Integer.TYPE), (short) 0); + public int intPropA; + public Property propLongA= new Property("PropLongA", 6, new Type(Long.TYPE), (short) 0); + public long longPropA; + public Property propFloatA= new Property("PropFloatA", 7, new Type(Float.TYPE), (short) 0); + public float floatPropA; + public Property propDoubleA= new Property("PropDoubleA", 8, new Type(Double.TYPE), (short) 0); + public double doublePropA; + public Property propStringA= new Property("PropStringA", 9, new Type(String.class), (short) 0); + public String stringPropA; + public Property propArrayByteA= new Property("PropArrayByteA", 10, new Type(byte[].class), (short) 0); + public byte[] arBytePropA; + public Property propTypeA= new Property("PropTypeA", 11, new Type(Type.class), (short) 0); + public Type typePropA; + public Property propObjectA= new Property("PropObjectA",12, new Type(Object.class), (short) 0); + public Object objectPropA; + public Property propAnyA= new Property("PropAnyA", 13, new Type(Any.class), (short) 0); + public Any anyPropA; + public Property propXInterfaceA= new Property("PropXInterfaceA", 13, new Type(Any.class), (short) 0); + public XInterface xInterfacePropA; + public Property propXWeakA= new Property("PropXWeakA", 13, new Type(Any.class), (short) 0); + public XWeak xWeakPropA; + public Property propEnum = + new Property("PropEnum", 14, new Type("com.sun.star.beans.PropertyState", TypeClass.ENUM), (short)0); + public com.sun.star.beans.PropertyState enumPropertyState = com.sun.star.beans.PropertyState.DEFAULT_VALUE; + // Test private, protected, package access, Anys as arguments and members, members with a value + + public Property propBoolB= new Property("PropBoolB", 101, new Type(Boolean.TYPE), (short) 0); + protected boolean boolPropB; + + public Property propBoolC= new Property("PropBoolC", 201, new Type(Boolean.TYPE), (short) 0); + boolean boolPropC; + + public Property propBoolD= new Property("PropBoolD", 301, new Type(Boolean.TYPE), (short) 0); + + public Property propBoolClass= new Property("PropBoolClass", 1001, new Type(Boolean.class), (short) 0); + public Boolean boolClassProp; + public Property propCharClass= new Property("PropCharClass", 1002, new Type(Character.class), (short) 0); + public Character charClassProp; + public Property propByteClass= new Property("PropByteClass", 1003, new Type(Byte.class), (short) 0); + public Byte byteClassProp; + public Property propShortClass= new Property("PropShortClass", 1004, new Type(Short.class), (short) 0); + public Short shortClassProp; + public Property propIntClass= new Property("PropIntClass", 1005, new Type(Integer.class), (short) 0); + public Integer intClassProp; + public Property propLongClass= new Property("PropLongClass", 1006, new Type(Long.class), (short) 0); + public Long longClassProp; + public Property propFloatClass= new Property("PropFloatClass", 1007, new Type(Float.class), (short) 0); + public Float floatClassProp; + public Property propDoubleClass= new Property("PropDoubleClass", 1008, new Type(Double.class), (short) 0); + public Double doubleClassProp; + + + public TestClass() + { + + super(); + // When adding properties then modify the getRegisteredProperties method + // registerProperty(String name, int handle, Type type, short attributes, String memberName) + registerProperty(propBoolA, "boolPropA"); + registerProperty(propCharA, "charPropA"); + registerProperty(propByteA, "bytePropA"); + registerProperty(propShortA, "shortPropA"); + registerProperty(propIntA, "intPropA"); + registerProperty(propLongA, "longPropA"); + registerProperty(propFloatA, "floatPropA"); + registerProperty(propDoubleA, "doublePropA"); + registerProperty(propStringA, "stringPropA"); + registerProperty(propArrayByteA, "arBytePropA"); + registerProperty(propTypeA, "typePropA"); + registerProperty(propObjectA, "objectPropA"); + registerProperty(propAnyA, "anyPropA"); + registerProperty(propXInterfaceA, "xInterfacePropA"); + registerProperty(propXWeakA, "xWeakPropA"); + registerProperty(propEnum,"enumPropertyState"); + registerProperty(propBoolB, "boolPropB"); + registerProperty(propBoolC, "boolPropC"); + registerProperty(propBoolD, "boolPropD"); + registerProperty(propBoolClass, "boolClassProp"); + registerProperty(propCharClass, "charClassProp"); + registerProperty(propByteClass, "byteClassProp"); + registerProperty(propShortClass, "shortClassProp"); + registerProperty(propIntClass, "intClassProp"); + registerProperty(propLongClass, "longClassProp"); + registerProperty(propFloatClass, "floatClassProp"); + registerProperty(propDoubleClass, "doubleClassProp"); + } + + /** When adding properties then modify the getRegisteredProperties method + */ + public Property[] getRegisteredProperties() + { + return new Property[] { + propBoolA, propCharA, propByteA, propShortA, + propIntA, propLongA, propFloatA, propDoubleA, + propStringA, propArrayByteA, propTypeA, propObjectA, + propAnyA, propXInterfaceA, propXWeakA, propEnum, propBoolB, + propBoolC, propBoolD, propBoolClass, propCharClass, + propByteClass, propShortClass, propIntClass, propLongClass, + propFloatClass, propDoubleClass + }; + + } + + public void test_convertPropertyValue() throws Exception + { + resetPropertyMembers(); + Object[] outOldVal= new Object[1]; + Object[] outNewVal= new Object[1]; + + Object value= Boolean.TRUE; + assertTrue(convertPropertyValue(propBoolA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Boolean); + assertEquals(outNewVal[0], value); + assertEquals(outOldVal[0], Boolean.FALSE); + + value= new Character('A'); + assertTrue(convertPropertyValue(propCharA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Character); + assertEquals(outNewVal[0], value); + assertEquals(outOldVal[0], new Character((char)0)); + + charPropA= 'B'; + assertTrue(convertPropertyValue(propCharA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Character); + assertEquals(outNewVal[0], value); + assertEquals(outOldVal[0], new Character('B')); + + value= Byte.valueOf((byte) 111); + assertTrue(convertPropertyValue(propByteA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Byte); + assertEquals(outNewVal[0], value); + + value= Short.valueOf((short) 112); + assertTrue(convertPropertyValue(propShortA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Short); + assertEquals(outNewVal[0], value); + + value= Integer.valueOf( 113); + assertTrue(convertPropertyValue(propIntA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Integer); + assertEquals(outNewVal[0], value); + + value= Long.valueOf(114); + assertTrue(convertPropertyValue(propLongA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Long); + assertEquals(outNewVal[0], value); + + value= new Float(3.14); + assertTrue(convertPropertyValue(propFloatA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Float); + assertEquals(outNewVal[0], value); + + value= new Double(3.145); + assertTrue(convertPropertyValue(propDoubleA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Double); + assertEquals(outNewVal[0], value); + + value= "string"; + assertTrue(convertPropertyValue(propStringA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof String); + assertEquals(outNewVal[0], value); + + value= new byte[]{1,2,3}; + arBytePropA= null; + assertTrue(convertPropertyValue(propArrayByteA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof byte[]); + assertEquals(outNewVal[0], value); + assertNull(outOldVal[0]); + + assertTrue(convertPropertyValue(propArrayByteA, outNewVal, outOldVal, value)); + assertNull(outOldVal[0]); + + value= new Type(XInterface.class); + assertTrue(convertPropertyValue(propTypeA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Type); + assertEquals(outNewVal[0], value); + + value= new Object(); // TypeClass.VOID + assertTrue(convertPropertyValue(propObjectA, outNewVal, outOldVal, value)); + assertEquals(outNewVal[0], value); + + value= Integer.valueOf(111); + assertTrue(convertPropertyValue(propObjectA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Integer); + assertEquals(outNewVal[0], value); + + value= new ComponentBase(); + assertTrue(convertPropertyValue(propObjectA, outNewVal, outOldVal, value)); + assertEquals(outNewVal[0], value); + + value= Integer.valueOf(111); + assertTrue(convertPropertyValue(propAnyA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Any); + assertEquals(((Any)outNewVal[0]).getType(), new Type(Integer.class)); + assertEquals(((Any)outNewVal[0]).getObject(), value); + + XWeak oWeak= new ComponentBase(); + value= oWeak; + // The returned Any must contain an XInterface + assertTrue(convertPropertyValue(propAnyA, outNewVal, outOldVal, value)); + assertEquals(((Any) outNewVal[0]).getType(), new Type(XInterface.class)); + assertSame(((Any) outNewVal[0]).getObject(), oWeak); + + value= new ComponentBase(); + assertTrue(convertPropertyValue(propXInterfaceA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof XInterface); + assertEquals(outNewVal[0], value); + assertTrue(convertPropertyValue(propXWeakA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof XWeak); + assertEquals(outNewVal[0], value); + + value = com.sun.star.beans.PropertyState.DIRECT_VALUE; + assertTrue(convertPropertyValue(propEnum, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof com.sun.star.uno.Enum); + assertEquals(outNewVal[0], value); + + // Any arguments ------------------------------------------------------------------ + value= new Any( new Type(Integer.class),Integer.valueOf(111)); + assertTrue(convertPropertyValue(propIntA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Integer); + assertEquals(outNewVal[0], ((Any) value).getObject()); + + value= new Any(new Type(Boolean.class), Boolean.TRUE); + assertTrue(convertPropertyValue(propBoolA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Boolean); + assertEquals(outNewVal[0], ((Any) value).getObject()); + + //Character, Byte, Short, Long + // must fail + try { + value= new Any(new Type(Object.class), new Object()); + fail("java.lang.IllegalArgumentException expected"); + assertTrue(convertPropertyValue(propObjectA, outNewVal, outOldVal, value)); + assertTrue(convertPropertyValue(propAnyA, outNewVal, outOldVal, value)); + } catch (java.lang.IllegalArgumentException e) { + logger.log(Level.FINE, "java.lang.IllegalArgumentException caught"); + } + + value= new Any(new Type(Integer.class), Integer.valueOf(111)); + assertTrue(convertPropertyValue(propObjectA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Integer); + assertEquals(outNewVal[0], ((Any)value).getObject()); + assertTrue(convertPropertyValue(propAnyA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Any); + assertEquals(((Any) outNewVal[0]).getType(), ((Any) value).getType()); + assertEquals(((Any) outNewVal[0]).getObject(), ((Any) value).getObject()); + + value= new Any(new Type(XInterface.class), new ComponentBase()); + assertTrue(convertPropertyValue(propObjectA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof XInterface); + assertSame(outNewVal[0], ((Any) value).getObject()); + assertTrue(convertPropertyValue(propXInterfaceA, outNewVal, outOldVal, value)); + assertSame(outNewVal[0], ((Any) value).getObject()); + + value= new Any(new Type(byte[].class), new byte[]{1,2,3}); + assertTrue(convertPropertyValue(propArrayByteA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof byte[]); + + // test private, protected, package fields + value= Boolean.TRUE; + assertTrue(convertPropertyValue(propBoolB, outNewVal, outOldVal, value)); + assertEquals(((Boolean)value).booleanValue(), ((Boolean) outNewVal[0]).booleanValue()); + assertTrue(convertPropertyValue(propBoolC, outNewVal, outOldVal, value)); + assertEquals(((Boolean)value).booleanValue(), ((Boolean) outNewVal[0]).booleanValue()); + // must fail because the member boolPropD is private + try{ + convertPropertyValue(propBoolD, outNewVal, outOldVal, value); + fail("com.sun.star.lang.WrappedTargetException expected"); + } catch (com.sun.star.lang.WrappedTargetException e) { + logger.log(Level.FINE, "com.sun.star.lang.WrappedTargetException caught"); + } + + // Properties member of type Byte,Short etc. + value= Boolean.TRUE; + assertTrue(convertPropertyValue(propBoolClass, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Boolean); + assertEquals(outNewVal[0], value); + + value= new Character('A'); + assertTrue(convertPropertyValue(propCharClass, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Character); + assertEquals(outNewVal[0], value); + + value= Byte.valueOf((byte) 111); + assertTrue(convertPropertyValue(propByteClass, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Byte); + assertEquals(outNewVal[0], value); + + value= Short.valueOf((short) 112); + assertTrue(convertPropertyValue(propShortClass, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Short); + assertEquals(outNewVal[0], value); + + value= Integer.valueOf(113); + assertTrue(convertPropertyValue(propIntClass, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Integer); + assertEquals(outNewVal[0], value); + + value= Long.valueOf(114); + assertTrue(convertPropertyValue(propLongClass, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Long); + assertEquals(outNewVal[0], value); + + value= new Float(3.14); + assertTrue(convertPropertyValue(propFloatClass, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Float); + assertEquals(outNewVal[0], value); + + value= new Double(3.145); + assertTrue(convertPropertyValue(propDoubleA, outNewVal, outOldVal, value)); + assertTrue(outNewVal[0] instanceof Double); + assertEquals(outNewVal[0], value); + } + + public void test_setPropertyValueNoBroadcast() throws Exception + { + resetPropertyMembers(); + + Object value= Boolean.TRUE; + setPropertyValueNoBroadcast(propBoolA, value); + assertEquals(boolPropA, ((Boolean) value).booleanValue()); + + value= new Character('A'); + setPropertyValueNoBroadcast(propCharA, value); + assertEquals(charPropA, ((Character) value).charValue()); + + value= Byte.valueOf((byte) 111); + setPropertyValueNoBroadcast(propByteA, value); + assertEquals(bytePropA, ((Byte)value).byteValue()); + + value= Short.valueOf((short) 112); + setPropertyValueNoBroadcast(propShortA, value); + assertEquals(shortPropA, ((Short) value).shortValue()); + + value= Integer.valueOf( 113); + setPropertyValueNoBroadcast(propIntA, value); + assertEquals(intPropA, ((Integer) value).intValue()); + + value= Long.valueOf(114); + setPropertyValueNoBroadcast(propLongA, value); + assertEquals(longPropA, ((Long) value).longValue()); + + value= new Float(3.14); + setPropertyValueNoBroadcast(propFloatA, value); + assertEquals(floatPropA, ((Float) value).floatValue(), 0.0f); + + value= new Double(3.145); + setPropertyValueNoBroadcast(propDoubleA, value); + assertEquals(doublePropA, ((Double) value).doubleValue(), 0.0f); + + value= "string"; + setPropertyValueNoBroadcast(propStringA, value); + assertEquals(stringPropA, value); + + value= new byte[]{1,2,3}; + setPropertyValueNoBroadcast(propArrayByteA, value); + assertEquals(arBytePropA, value); + + value= new Type(XInterface.class); + setPropertyValueNoBroadcast(propTypeA, value); + assertEquals(typePropA, value); + + value= Integer.valueOf(111); + setPropertyValueNoBroadcast(propObjectA, value); + assertEquals(objectPropA, value); + + value= new ComponentBase(); + setPropertyValueNoBroadcast(propObjectA, value); + assertEquals(objectPropA, value); + + value= new Any( new Type(Integer.TYPE), Integer.valueOf(111)); + setPropertyValueNoBroadcast(propAnyA, value); + assertTrue(util.anyEquals(anyPropA, value)); + + value= new ComponentBase(); + setPropertyValueNoBroadcast(propXInterfaceA, value); + assertTrue(xInterfacePropA instanceof XInterface); + assertEquals(xInterfacePropA, value); + + setPropertyValueNoBroadcast(propXWeakA, value); + assertTrue(xInterfacePropA instanceof XWeak); + assertEquals(xInterfacePropA, value); + + value = com.sun.star.beans.PropertyState.AMBIGUOUS_VALUE; + setPropertyValueNoBroadcast(propEnum, value); + assertSame(enumPropertyState, value); + + value= Boolean.TRUE; + setPropertyValueNoBroadcast(propBoolB, value); + assertEquals(boolPropB, ((Boolean) value).booleanValue()); + + setPropertyValueNoBroadcast(propBoolC, value); + assertEquals(boolPropC, ((Boolean) value).booleanValue()); + + // must fail because the member boolPropD is private + try { + setPropertyValueNoBroadcast(propBoolD, value); + fail("com.sun.star.lang.WrappedTargetException expected"); + } catch (com.sun.star.lang.WrappedTargetException e) { + logger.log(Level.FINE, "com.sun.star.lang.WrappedTargetException caught"); + } + } + + void resetPropertyMembers() + { + boolPropA= false; + charPropA= (char) 0; + bytePropA= 0; + shortPropA= 0; + intPropA= 0; + longPropA= 0; + floatPropA= 0; + doublePropA= 0.; + stringPropA= null; + arBytePropA= null; + typePropA= null; + objectPropA= null; + anyPropA= null; + xInterfacePropA= null; + xWeakPropA= null; + enumPropertyState = com.sun.star.beans.PropertyState.DEFAULT_VALUE; + boolPropB= false; + boolPropC= false; + boolClassProp= null; + charClassProp= null; + byteClassProp= null; + shortClassProp= null; + intClassProp= null; + longClassProp= null; + floatClassProp= null; + doubleClassProp= null; + } +} + +class TestClass2 extends PropertySet +{ + + public char charA; + protected char charB; + char charC; + + int intMemberA; + + public Character charClassA; + protected Character charClassB; + Character charClassC; + + void test_registerProperty1() throws Exception + { + registerProperty("PropChar", new Type(char.class), (short) 0, "PropChar"); + registerProperty("PropInt", new Type(int.class), (short) 0, "PropInt"); + registerProperty("PropString", new Type(String.class), (short) 0, "PropString"); + + XPropertySetInfo info= getPropertySetInfo(); + Property[] props= info.getProperties(); + for (int j= 0; j < props.length; j++) + { + boolean result= false; + Property aProp= props[j]; + if (aProp.Name.equals("PropChar") && aProp.Type.equals(new Type(char.class)) && + aProp.Attributes == 0) + result= true; + else if (aProp.Name.equals("PropInt") && aProp.Type.equals(new Type(int.class)) && + aProp.Attributes == 0) + result= true; + else if (aProp.Name.equals("PropString") && aProp.Type.equals(new Type(String.class)) && + aProp.Attributes == 0) + result= true; + assertTrue(result); + } + } + + void test_registerProperty2() throws Exception + { + System.out.println("registerProperty Test 2"); + + registerProperty("charA", "charA", (short) 0); + registerProperty("charB", "charB", (short) 0); + registerProperty("charC", "charC", (short) 0); + registerProperty("charClassB", "charClassB", PropertyAttribute.MAYBEVOID); + registerProperty("IntProp", "intMemberA", (short) 0); + + XPropertySetInfo info= getPropertySetInfo(); + Property[] props= info.getProperties(); + for (int j= 0; j < props.length; j++) + { + boolean result= false; + Property aProp= props[j]; + if (aProp.Name.equals("charA") && aProp.Type.equals(new Type(char.class)) && + aProp.Attributes == 0) + result= true; + else if (aProp.Name.equals("charB") && aProp.Type.equals(new Type(char.class)) && + aProp.Attributes == 0) + result= true; + else if (aProp.Name.equals("charC") && aProp.Type.equals(new Type(char.class)) && + aProp.Attributes == 0) + result= true; + else if (aProp.Name.equals("charClassB") && aProp.Type.equals(new Type(char.class)) && + aProp.Attributes == PropertyAttribute.MAYBEVOID) + result= true; + else if (aProp.Name.equals("IntProp") && aProp.Type.equals(new Type(int.class)) && + aProp.Attributes == 0) + result= true; + assertTrue(result); + } + Object val= new Character('A'); + setPropertyValue("charA", val); + assertEquals(val, getPropertyValue("charA")); + setPropertyValue("charClassB",val); + assertEquals(val, getPropertyValue("charClassB")); + val= Integer.valueOf(111); + setPropertyValue("IntProp",val); + assertEquals(val, getPropertyValue("IntProp")); + } +} + +class util +{ + // An Object is considered an Any with TypeClass.VOID and no value. + static boolean anyEquals(Object val1, Object val2) + { + Object obj1= null; + Object obj2= null; + Type t1= null; + Type t2= null; + if (val1 instanceof Any) + { + obj1= ((Any) val1).getObject(); + t1= ((Any) val1).getType(); + } + else + obj1= val1; + + if (val2 instanceof Any) + { + obj2= ((Any) val2).getObject(); + t2= ((Any) val2).getType(); + } + else + obj2= val2; + + if (obj1 != null && obj1.equals(obj2)) + return true; + else if ((obj1 == null && obj2 == null) && t1 != null && t1.equals(t2)) + return true; + return false; + } + + // returns true if obj is an any that contains a void or interface type and the + // object is null + static boolean isVoidAny(Object obj) + { + boolean ret= false; + if(obj instanceof Any) + { + Any a= (Any) obj; + if( a.getType().getTypeClass().equals( TypeClass.INTERFACE) + && a.getObject() == null) { + ret= true; + } + else if( a.getType().equals( new Type(void.class)) && a.getObject() == null) { + ret= true; + } + } + return ret; + } +} + +class Listener implements XPropertyChangeListener, XVetoableChangeListener, +XPropertiesChangeListener +{ + int nChangeCalled; + int nPropertiesChange; + int nVetoCalled; + boolean bVeto= false; + PropertyChangeEvent evt; + PropertyChangeEvent[] arEvt; + // XPropertyChangeListener + public void propertyChange(PropertyChangeEvent evt ) + { + nChangeCalled++; + this.evt= evt; + } + + //VetoableChangeListener + public void vetoableChange(PropertyChangeEvent evt ) throws PropertyVetoException + { + nVetoCalled++; + this.evt= evt; + if (bVeto) + throw new PropertyVetoException(); + } + + public void disposing( /*IN*/EventObject Source ) + { + } + + public void reset() + { + nChangeCalled= 0; + nPropertiesChange= 0; + nVetoCalled= 0; + evt= null; + arEvt= null; + bVeto= false; + } + // XPropertiesChangeListener + public void propertiesChange(PropertyChangeEvent[] propertyChangeEvent) + { + nPropertiesChange++; + arEvt= propertyChangeEvent; + } + +} diff --git a/javaunohelper/test/com/sun/star/lib/uno/helper/ProxyProvider.java b/javaunohelper/test/com/sun/star/lib/uno/helper/ProxyProvider.java new file mode 100644 index 000000000..a28794434 --- /dev/null +++ b/javaunohelper/test/com/sun/star/lib/uno/helper/ProxyProvider.java @@ -0,0 +1,95 @@ +/* + * 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.lib.uno.helper; +import com.sun.star.uno.Type; +import com.sun.star.lib.uno.typedesc.TypeDescription; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.lang.XEventListener; +import com.sun.star.uno.IQueryInterface; +import com.sun.star.lib.uno.environments.java.java_environment; + + +public class ProxyProvider +{ + private static java_environment env= new java_environment(null); + + /** returns Holder proxy objects for the specified interface. If the method is called + * several times with the same arguments then each time a new HolderProxy is returned. + * Then all HolderProxy s refer to the same Proxy object. + * The proxy can be queried for XEventListener. On the returned proxy disposing can be called + * + */ + public static Object createProxy(Object obj, Class iface) + { + + Object retVal= null; + if (obj == null || iface == null || !iface.isInstance(obj) ) + return retVal; + + Type type= new Type(TypeDescription.getTypeDescription(iface)); + new Type(TypeDescription.getTypeDescription(com.sun.star.lang.XEventListener.class)); + // find the object identifier + String sOid= UnoRuntime.generateOid(obj); + retVal= env.getRegisteredInterface(sOid, type); + // if retVal == null then probably not registered + if (retVal == null) + { + Object aProxy = new Proxy(sOid); + String[] arOid = new String[] + {sOid}; + retVal= env.registerInterface(aProxy, arOid, type); + } + return retVal; + } +} + +class Proxy implements IQueryInterface, XEventListener +{ + private String oid; + Proxy(String oid) { + this.oid = oid; + } + + public String getOid() { + return oid; + } + + public boolean isSame(Object object) { + if (object instanceof IQueryInterface) + { + IQueryInterface iquery = (IQueryInterface) object; + return iquery.getOid().equals(oid); + } + + String oidObj = UnoRuntime.generateOid(object); + return oidObj.equals(oid); + } + + public Object queryInterface(Type type) { + return null; + } + + public void disposing(com.sun.star.lang.EventObject eventObject) { + } + +} + + + + diff --git a/javaunohelper/test/com/sun/star/lib/uno/helper/UnoUrlTest.java b/javaunohelper/test/com/sun/star/lib/uno/helper/UnoUrlTest.java new file mode 100644 index 000000000..d12c5aee4 --- /dev/null +++ b/javaunohelper/test/com/sun/star/lib/uno/helper/UnoUrlTest.java @@ -0,0 +1,252 @@ +/* + * 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.lib.uno.helper; +public class UnoUrlTest { + + private UnoUrlTest() { + } + + + private void fail(String msg) { + System.err.println(msg); + System.exit(1); + } + + private static void log(String msg) { + System.out.println(msg); + } + + private void assertTrue(boolean b) { + if (!b) + fail("boolean assertion failed"); + } + + private void assertEquals(String expected, String actual) { + if (!expected.equals(actual)) { + fail("Expected: '"+ expected + "' but was: '"+actual+"'"); + } + } + + private void assertEquals(int expected, int actual) { + if (expected != actual) { + fail("Expected: "+ expected + " but was: "+actual); + } + } + + public void testStart1() { + try { + UnoUrl url = UnoUrl.parseUnoUrl("uno:x;y;z"); + assertTrue((url != null)); + assertEquals("x", url.getConnection()); + } catch (com.sun.star.lang.IllegalArgumentException e) { + fail("Caught exception:" + e.getMessage()); + } + } + + public void testStart2() { + try { + UnoUrl.parseUnoUrl("uno1:x;y;z"); + fail("Should throw an exception"); + } catch (com.sun.star.lang.IllegalArgumentException e) { + } + } + + public void testStart3() { + try { + UnoUrl.parseUnoUrl("un:x;y;z"); + fail("Should throw an exception"); + } catch (com.sun.star.lang.IllegalArgumentException e) { + } + } + + public void testStart4() { + try { + UnoUrl url = UnoUrl.parseUnoUrl("x;y;z"); + assertTrue((url != null)); + assertEquals("y", url.getProtocol()); + } catch (com.sun.star.lang.IllegalArgumentException e) { + fail("Caught exception:" + e.getMessage()); + } + } + + public void testParam1() { + try { + UnoUrl.parseUnoUrl("uno:"); + fail("Should throw an exception"); + } catch (com.sun.star.lang.IllegalArgumentException e) { + } + } + + public void testParam2() { + try { + UnoUrl.parseUnoUrl("uno:a;"); + fail("Should throw an exception"); + } catch (com.sun.star.lang.IllegalArgumentException e) { + } + } + + public void testPartName1() { + try { + UnoUrl.parseUnoUrl("uno:abc!abc;b;c"); + fail("Should throw an exception"); + } catch (com.sun.star.lang.IllegalArgumentException e) { + } + } + + public void testOID1() { + try { + UnoUrl.parseUnoUrl("uno:x;y;ABC<ABC"); + fail("Should throw an exception"); + } catch (com.sun.star.lang.IllegalArgumentException e) { + } + } + + public void testOIDandParams1() { + try { + UnoUrl url = UnoUrl.parseUnoUrl("uno:x,key9=val9;y;ABC"); + assertTrue((url != null)); + assertEquals("ABC", url.getRootOid()); + assertEquals(1, url.getConnectionParameters().size()); + assertEquals("val9", url.getConnectionParameters().get("key9")); + } catch (com.sun.star.lang.IllegalArgumentException e) { + fail(e.getMessage()); + } + } + + public void testOIDandParams2() { + try { + UnoUrl url = UnoUrl.parseUnoUrl("uno:x,key1=val1,k2=v2;y,k3=v3;ABC()!/"); + assertTrue((url != null)); + assertEquals("ABC()!/", url.getRootOid()); + assertEquals(2, url.getConnectionParameters().size()); + assertEquals(1, url.getProtocolParameters().size()); + } catch (com.sun.star.lang.IllegalArgumentException e) { + fail("Caught exception:" + e.getMessage()); + } + } + + public void testParams1() { + try { + UnoUrl.parseUnoUrl("uno:x,abc!abc=val;y;ABC"); + fail("Should throw an exception"); + } catch (com.sun.star.lang.IllegalArgumentException e) { + } + } + + public void testParams2() { + try { + UnoUrl.parseUnoUrl("uno:x,abc=val<val;y;ABC"); + fail("Should throw an exception"); + } catch (com.sun.star.lang.IllegalArgumentException e) { + } + } + + public void testParams3() { + try { + UnoUrl url = UnoUrl.parseUnoUrl("uno:x,abc=val!()val;y;ABC"); + assertTrue((url != null)); + assertEquals(1, url.getConnectionParameters().size()); + } catch (com.sun.star.lang.IllegalArgumentException e) { + fail("Caught exception:" + e.getMessage()); + } + } + + public void testCommon() { + try { + UnoUrl url = + UnoUrl.parseUnoUrl( + "socket,host=localhost,port=2002;urp;StarOffice.ServiceManager"); + assertTrue((url != null)); + assertEquals("StarOffice.ServiceManager", url.getRootOid()); + assertEquals("socket", url.getConnection()); + assertEquals("urp", url.getProtocol()); + assertEquals("2002", url.getConnectionParameters().get("port")); + } catch (com.sun.star.lang.IllegalArgumentException e) { + fail("Caught exception:" + e.getMessage()); + } + } + + public void testUTF() { + try { + UnoUrl url = + UnoUrl.parseUnoUrl( + "socket,host=localhost,horst=abc%c3%9c%c3%a4ABC%41%2c%2C,port=2002;urp;StarOffice.ServiceManager"); + assertEquals("abcÜäABCA,,", url.getConnectionParameters().get("horst")); + assertEquals( + "host=localhost,horst=abc%c3%9c%c3%a4ABC%41%2c%2C,port=2002", + url.getConnectionParametersAsString()); + } catch (com.sun.star.lang.IllegalArgumentException e) { + fail("Caught exception:" + e.getMessage()); + } + + } + + public void testUTF1() { + try { + UnoUrl.parseUnoUrl("uno:x,abc=val%4t;y;ABC"); + fail("Should throw an exception"); + } catch (com.sun.star.lang.IllegalArgumentException e) { + } + } + + + public static void main(String args[]) { + UnoUrlTest t = new UnoUrlTest(); + + log("Running test case 1"); + t.testStart1(); + log("Running test case 2"); + t.testStart2(); + log("Running test case 3"); + t.testStart3(); + log("Running test case 4"); + t.testStart4(); + + log("Running test case 5"); + t.testParam1(); + log("Running test case 6"); + t.testParam2(); + + log("Running test case 7"); + t.testPartName1(); + + log("Running test case 8"); + t.testOID1(); + + log("Running test case 9"); + t.testOIDandParams1(); + log("Running test case 10"); + t.testOIDandParams2(); + + log("Running test case 11"); + t.testParams1(); + log("Running test case 12"); + t.testParams2(); + log("Running test case 13"); + t.testParams3(); + + log("Running test case 14"); + t.testCommon(); + + log("Running test case 15"); + t.testUTF(); + log("Running test case 16"); + t.testUTF1(); + } +} diff --git a/javaunohelper/test/com/sun/star/lib/uno/helper/WeakBase_Test.java b/javaunohelper/test/com/sun/star/lib/uno/helper/WeakBase_Test.java new file mode 100644 index 000000000..a649f1682 --- /dev/null +++ b/javaunohelper/test/com/sun/star/lib/uno/helper/WeakBase_Test.java @@ -0,0 +1,149 @@ +/* + * 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.lib.uno.helper; + +import com.sun.star.bridge.XBridgeSupplier2; +import com.sun.star.lang.XTypeProvider; +import com.sun.star.uno.XAdapter; +import com.sun.star.uno.Type; +import com.sun.star.uno.XReference; +import com.sun.star.uno.XWeak; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import org.junit.Test; +import util.WaitUnreachable; + +public class WeakBase_Test +{ + + private static final Logger logger = Logger.getLogger(WeakBase_Test.class.getName()); + + @Test public void getTypes() throws Exception + { + logger.log(Level.INFO, "Testing WeakBase.getTypes"); + SomeClass comp= new SomeClass(); + + Type[] types= comp.getTypes(); //XWeak,XTypeProvider,XReference,XBridgeSupplier2 + assertEquals(types.length, 4); + for (int c= 0; c < types.length; c++) + { + boolean result= false; + if (types[c].equals( new Type( XWeak.class))) + result= true; + else if (types[c].equals(new Type(XTypeProvider.class))) + result= true; + else if (types[c].equals(new Type(XReference.class))) + result= true; + else if (types[c].equals(new Type(XBridgeSupplier2.class))) + result= true; + assertTrue(result); + } + + Foo1 f1= new Foo1(); + Foo1 f2= new Foo1(); + Type[] t1= f1.getTypes(); + Type[] t2= f2.getTypes(); + assertArrayEquals(t1, t2); + new Foo2(); + } + + @Test public void queryAdapter() throws Exception + { + logger.log(Level.INFO, "Testing WeakBase.queryAdapter, XAdapter tests"); + SomeClass comp= new SomeClass(); + + XAdapter adapter= comp.queryAdapter(); + MyRef aRef1= new MyRef(); + MyRef aRef2= new MyRef(); + adapter.addReference(aRef1); + adapter.addReference(aRef2); + + assertSame(adapter.queryAdapted(), comp); + WaitUnreachable u = new WaitUnreachable(comp); + comp= null; + u.waitUnreachable(); + assertEquals(aRef1.nDisposeCalled, 1); + assertEquals(aRef2.nDisposeCalled, 1); + assertNull(adapter.queryAdapted()); + adapter.removeReference(aRef1); // should not do any harm + adapter.removeReference(aRef2); + + comp= new SomeClass(); + adapter= comp.queryAdapter(); + aRef1.nDisposeCalled= 0; + aRef2.nDisposeCalled= 0; + + adapter.addReference(aRef1); + adapter.addReference(aRef2); + + adapter.removeReference(aRef1); + u = new WaitUnreachable(comp); + comp= null; + u.waitUnreachable(); + assertEquals(aRef1.nDisposeCalled, 0); + assertEquals(aRef2.nDisposeCalled, 1); + } +} + +class OtherClass extends WeakBase implements XBridgeSupplier2 +{ + + public Object createBridge(Object obj, byte[] values, short param, short param3) throws com.sun.star.lang.IllegalArgumentException + { + return null; + } +} + +class SomeClass extends OtherClass implements XReference +{ + + public void dispose() + { + } + +} + +class MyRef implements XReference +{ + int nDisposeCalled; + + public void dispose() + { + nDisposeCalled++; + } +} + +class Foo1 extends WeakBase +{ +} + +class Foo2 extends WeakBase +{ +} + +class Foo3 extends Foo1 +{ +} diff --git a/javaunohelper/util/manifest b/javaunohelper/util/manifest new file mode 100644 index 000000000..5c77968cd --- /dev/null +++ b/javaunohelper/util/manifest @@ -0,0 +1 @@ +UNO-Type-Path: |