diff options
author | Joachim Lingner <jl@openoffice.org> | 2004-04-19 14:37:36 +0000 |
---|---|---|
committer | Joachim Lingner <jl@openoffice.org> | 2004-04-19 14:37:36 +0000 |
commit | 43cc8abfb0a41878c4e78fd3b868b1d4f344c610 (patch) | |
tree | d8e7e35d55704a75b131eb5d7c92758218fc627d /jvmfwk/plugins | |
parent | c7d0bfee4c06030dae1138f9eea4bd127a71efd2 (diff) |
#i20052# plugin lib for java framework
Diffstat (limited to 'jvmfwk/plugins')
-rw-r--r-- | jvmfwk/plugins/sunmajor/pluginlib/makefile.mk | 121 | ||||
-rw-r--r-- | jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx | 434 | ||||
-rw-r--r-- | jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.map | 8 | ||||
-rw-r--r-- | jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx | 563 | ||||
-rw-r--r-- | jvmfwk/plugins/sunmajor/pluginlib/sunversion.hxx | 151 |
5 files changed, 1277 insertions, 0 deletions
diff --git a/jvmfwk/plugins/sunmajor/pluginlib/makefile.mk b/jvmfwk/plugins/sunmajor/pluginlib/makefile.mk new file mode 100644 index 000000000000..c2cefb325b3c --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/makefile.mk @@ -0,0 +1,121 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1 $ +# +# last change: $Author: jl $ $Date: 2004-04-19 15:37:36 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (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.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/..$/..$/.. + +PRJNAME= jvmfwk + +TARGET = plugin + +ENABLE_EXCEPTIONS=TRUE +BOOTSTRAP_SERVICE=FALSE + +LIBTARGET=NO + +UNOCOMPONENT1=sunjavaplugin + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +DLLPRE = + +# ------------------------------------------------------------------ + +#.INCLUDE : ..$/cppumaker.mk +.IF "$(SOLAR_JAVA)"!="" +SLOFILES= \ + $(SLO)$/sunjavaplugin.obj \ + $(SLO)$/javainfo.obj \ + $(SLO)$/sunversion.obj \ + $(SLO)$/windows.obj + +LIB1OBJFILES= \ + $(SLO)$/sunjavaplugin.obj \ + $(SLO)$/javainfo.obj \ + $(SLO)$/sunversion.obj \ + $(SLO)$/windows.obj + + + +LIB1TARGET=$(SLB)$/$(UNOCOMPONENT1).lib + +SHL1TARGET= $(UNOCOMPONENT1) +SHL1STDLIBS= \ + $(CPPULIB) \ + $(CPPUHELPER) \ + $(SALLIB) + +.IF "$(OS)" == "WNT" +SHL1STDLIBS += advapi32.lib +.ENDIF # WNT + +SHL1VERSIONMAP = sunjavaplugin.map +SHL1DEPN= +SHL1IMPLIB= i$(UNOCOMPONENT1) +SHL1LIBS= $(LIB1TARGET) +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +DEF1NAME= $(SHL1TARGET) +.ENDIF + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx b/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx new file mode 100644 index 000000000000..90e497b190b9 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.cxx @@ -0,0 +1,434 @@ +/************************************************************************* + * + * $RCSfile: sunjavaplugin.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jl $ $Date: 2004-04-19 15:36:12 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#if OSL_DEBUG_LEVEL > 0 +#include <stdio.h> +#endif + +#include "external/boost/scoped_array.hpp" +#include "osl/diagnose.h" +#include "rtl/ustring.hxx" +#include "osl/module.hxx" +#include "osl/mutex.hxx" +#include "osl/thread.hxx" +#include "rtl/instance.hxx" +#include "osl/getglobalmutex.hxx" +#include <setjmp.h> +#include <signal.h> +#include <stack> + +#include "jni.h" +#include "rtl/byteseq.hxx" +#include "jvmfwk/vendorplugin.h" +#include "javainfo.hxx" + + +#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) + +namespace { + +struct Init +{ + osl::Mutex * operator()() + { + static osl::Mutex aInstance; + return &aInstance; + } +}; +osl::Mutex * getPluginMutex() +{ + return rtl_Instance< osl::Mutex, Init, ::osl::MutexGuard, + ::osl::GetGlobalMutex >::create( + Init(), ::osl::GetGlobalMutex()); +} + +rtl::OUString getRuntimeLib(const rtl::ByteSequence & data) +{ + const sal_Unicode* chars = (sal_Unicode*) data.getConstArray(); + sal_Int32 len = data.getLength(); + return rtl::OUString(chars, len / 2); +} + +jmp_buf jmp_jvm_abort; +sig_atomic_t g_bInGetJavaVM = 0; + +void abort_handler() +{ + // If we are within JNI_CreateJavaVM then we jump back into getJavaVM + if( g_bInGetJavaVM != 0 ) + { + fprintf( stderr, "JavaVM: JNI_CreateJavaVM called _exit, caught by abort_handler in javavm.cxx\n"); + longjmp( jmp_jvm_abort, 0); + } +} + +} +namespace cssu = com::sun::star::uno; +extern "C" +javaPluginError getAllJavaInfos( rtl_uString *sMinVersion, + rtl_uString *sMaxVersion, + rtl_uString * *arExcludeList, + sal_Int32 nLenList, + JavaInfo*** parJavaInfo, + sal_Int32 *nLenInfoList) +{ + if (parJavaInfo == NULL || nLenInfoList == NULL) + return JFW_PLUGIN_E_INVALID_ARG; + JavaInfo** arInfo = NULL; + try + { + //check if we know all the required features + + cssu::Sequence<rtl::OUString> seqExclude((rtl::OUString*)(rtl_uString**)arExcludeList, nLenList); + + rtl::OUString sMin((rtl_uString*) sMinVersion); + + std::vector<stoc_javadetect::JavaInfo> vec = + stoc_javadetect::JavaInfo::createAllInfo(sMin, seqExclude, 0); + + arInfo = (JavaInfo**) rtl_allocateMemory(vec.size() * sizeof (JavaInfo*)); +// JavaInfo * (_arInfo[] = (JavaInfo*(*)[])arInfo; + int j = 0; + rtl::OUString sVendor(OUSTR("Sun Microsystems Inc.")); + + + typedef std::vector<stoc_javadetect::JavaInfo>::iterator cit; + for (cit i = vec.begin(); i != vec.end(); i++, j++) + { + arInfo[j] = (JavaInfo*) rtl_allocateMemory(sizeof JavaInfo); + JavaInfo* pInfo = arInfo[j]; + pInfo->sVendor = sVendor.pData; + rtl_uString_acquire(sVendor.pData); + pInfo->sLocation = i->usJavaHome.pData; + rtl_uString_acquire(i->usJavaHome.pData); + pInfo->sVersion = i->getVersion().pData; + rtl_uString_acquire(pInfo->sVersion); + pInfo->nFeatures = i->supportsAccessibility() ? 1 : 0; +#ifdef UNX + pInfo->nRequirements = JFW_REQUIRE_NEEDRESTART; +#else + pInfo->nRequirements = 0x0l; +#endif + rtl::OUString sRuntimeLib = i->usRuntimeLib; + rtl::ByteSequence byteSeq( (sal_Int8*) sRuntimeLib.pData->buffer, + sRuntimeLib.getLength() * sizeof(sal_Unicode)); + pInfo->arVendorData = byteSeq.get(); + rtl_byte_sequence_acquire(pInfo->arVendorData); + } + + *nLenInfoList = vec.size(); + } + catch(stoc_javadetect::JavaInfo::MalformedVersionException&) + { + return JFW_PLUGIN_E_WRONG_VERSION_FORMAT; + } + + *parJavaInfo = arInfo; + return JFW_PLUGIN_E_NONE; +} + +extern "C" +javaPluginError getJavaInfoByPath( + rtl_uString *path, + rtl_uString *sMinVersion, + rtl_uString *sMaxVersion, + rtl_uString * *arExcludeList, + sal_Int32 nLenList, + JavaInfo ** ppInfo) +{ + javaPluginError errcode = JFW_PLUGIN_E_NONE; + if (ppInfo == NULL) + return JFW_PLUGIN_E_INVALID_ARG; + try + { + rtl::OUString sPath((rtl_uString*)path); + stoc_javadetect::JavaInfo info(sPath); + //check if the version meets the requirements + const rtl::OUString& sVersion = info.getVersion(); + rtl::OUString sTheMinVersion((rtl_uString*) sMinVersion); + + if (sTheMinVersion.getLength() > 0) + { + int nRes = + stoc_javadetect::JavaInfo::compareVersions( + sVersion, sTheMinVersion); + if (nRes < 0) + return JFW_PLUGIN_E_FAILED_REQUIREMENTS; + } + + rtl::OUString sTheMaxVersion((rtl_uString*) sMaxVersion); + if (sTheMaxVersion.getLength() > 0) + { + int nRes = + stoc_javadetect::JavaInfo::compareVersions( + sVersion, sTheMaxVersion); + if (nRes > 0) + return JFW_PLUGIN_E_FAILED_REQUIREMENTS; + } + + if (arExcludeList > 0) + { + for (int i = 0; i < nLenList; i++) + { + rtl::OUString sExVer((rtl_uString*) arExcludeList[i]); + int nRes = + stoc_javadetect::JavaInfo::compareVersions( + sVersion, sExVer); + if (nRes == 0) + return JFW_PLUGIN_E_FAILED_REQUIREMENTS; + } + } + + rtl::OUString sVendor(OUSTR("Sun Microsystems Inc.")); + JavaInfo * pInfo = (JavaInfo*) rtl_allocateMemory(sizeof (JavaInfo)); + pInfo->sVendor = sVendor.pData; + rtl_uString_acquire(sVendor.pData); + pInfo->sLocation = info.usJavaHome.pData; + rtl_uString_acquire(pInfo->sLocation); + pInfo->sVersion = info.getVersion().pData; + rtl_uString_acquire(pInfo->sVersion); + pInfo->nFeatures = info.supportsAccessibility() ? 1 : 0; +#ifdef UNX + pInfo->nRequirements = JFW_REQUIRE_NEEDRESTART; +#else + pInfo->nRequirements = 0l; +#endif + rtl::OUString sRuntimeLib = info.usRuntimeLib; + rtl::ByteSequence byteSeq( (sal_Int8*) sRuntimeLib.pData->buffer, + sRuntimeLib.getLength() * sizeof(sal_Unicode)); + pInfo->arVendorData = byteSeq.get(); + rtl_byte_sequence_acquire(pInfo->arVendorData); + + *ppInfo = pInfo; + } + catch(stoc_javadetect::JavaInfo::InitException& ) + { + errcode = JFW_PLUGIN_E_NO_JRE; + } + catch(stoc_javadetect::JavaInfo::MalformedVersionException& ) + { + errcode = JFW_PLUGIN_E_WRONG_VERSION_FORMAT; + } + catch(...) + { + errcode = JFW_PLUGIN_E_ERROR; + } + return errcode; +} + +/** starts a Java Virtual Machine. + <p> + The function shall ensure, that the VM does not abort the process + during instantiation. + </p> + */ +extern "C" +javaPluginError startJavaVirtualMachine( + const JavaInfo *pInfo, + const JavaVMOption* arOptions, + sal_Int32 cOptions, + JavaVM ** ppVm, + JNIEnv ** ppEnv) +{ + osl::MutexGuard guard(getPluginMutex()); + javaPluginError errcode = JFW_PLUGIN_E_NONE; + if ( pInfo == NULL || ppVm == NULL || ppEnv == NULL) + return JFW_PLUGIN_E_INVALID_ARG; + // On linux we load jvm with RTLD_GLOBAL. This is necessary for debugging, because + // libjdwp.so need a symbol (fork1) from libjvm which it only gets if the jvm is loaded + // witd RTLD_GLOBAL. On Solaris libjdwp.so is correctly linked with libjvm.so + rtl::OUString sRuntimeLib = getRuntimeLib(pInfo->arVendorData); + oslModule moduleRt = + osl_loadModule(sRuntimeLib.pData, SAL_LOADMODULE_DEFAULT); +#if defined(LINUX) + if ((moduleRt = osl_loadModule(sRuntimeLib.pData, + SAL_LOADMODULE_GLOBAL | SAL_LOADMODULE_NOW)) +#else + if ((moduleRt = osl_loadModule(sRuntimeLib.pData, SAL_LOADMODULE_DEFAULT)) == 0) +#endif + { + OSL_ASSERT(0); + rtl::OString msg = rtl::OUStringToOString( + sRuntimeLib, osl_getThreadTextEncoding()); + fprintf(stderr,"Could not load java runtime library : %s", + sRuntimeLib.getStr()); + return JFW_PLUGIN_E_ERROR; + } + +#ifdef UNX + rtl::OUString javaHome(RTL_CONSTASCII_USTRINGPARAM("JAVA_HOME=")); + javaHome += pInfo->sLocation; + rtl::OString osJavaHome = rtl::OUStringToOString( + javaHome, osl_getThreadTextEncoding()); + putenv(strdup(osJavaHome.getStr())); +#endif + + typedef jint JNICALL JNI_InitArgs_Type(void *); + typedef jint JNICALL JNI_CreateVM_Type(JavaVM **, JNIEnv **, void *); + rtl::OUString sSymbolCreateJava( + RTL_CONSTASCII_USTRINGPARAM("JNI_CreateJavaVM")); + + JNI_CreateVM_Type * pCreateJavaVM = (JNI_CreateVM_Type *) osl_getSymbol( + moduleRt, sSymbolCreateJava.pData); + if (!pCreateJavaVM) + { + OSL_ASSERT(0); + rtl::OString sLib = rtl::OUStringToOString( + sRuntimeLib, osl_getThreadTextEncoding()); + rtl::OString sSymbol = rtl::OUStringToOString( + sSymbolCreateJava, osl_getThreadTextEncoding()); + fprintf(stderr,"Java runtime library: %s does not export symbol %s !", + sLib.getStr(), sSymbol.getStr()); + return JFW_PLUGIN_E_ERROR; + } + + // The office sets a signal handler at startup. That causes a crash + // with java 1.3 under Solaris. To make it work, we set back the + // handler +#ifdef UNX + struct sigaction act; + act.sa_handler=SIG_DFL; + act.sa_flags= 0; + sigaction( SIGSEGV, &act, NULL); + sigaction( SIGPIPE, &act, NULL); + sigaction( SIGBUS, &act, NULL); + sigaction( SIGILL, &act, NULL); + sigaction( SIGFPE, &act, NULL); +#endif + + // Some testing with Java 1.4 showed that JavaVMOption.optionString has to + // be encoded with the system encoding (i.e., osl_getThreadTextEncoding): + JavaVMInitArgs vm_args; + + + boost::scoped_array<JavaVMOption> sarOptions( + new JavaVMOption[cOptions + 1]); + JavaVMOption * options = sarOptions.get(); + + // We set an abort handler which is called when the VM calls _exit during + // JNI_CreateJavaVM. This happens when the LD_LIBRARY_PATH does not contain + // all some directories of the Java installation. This is necessary for + // linux j2re1.3, 1.4 and Solaris j2re1.3. With a j2re1.4 on Solaris the + // LD_LIBRARY_PATH need not to be set anymore. + options[0].optionString= "abort"; + options[0].extraInfo= (void* )abort_handler; + int index = 1; + for (int i = 0; i < cOptions; i++) + { + options[i+1].optionString = arOptions[i].optionString; + options[i+1].extraInfo = arOptions[i].extraInfo; + } + + vm_args.version= JNI_VERSION_1_2; + vm_args.options= options; + vm_args.nOptions= cOptions + 1; + vm_args.ignoreUnrecognized= JNI_TRUE; + + /* We set a global flag which is used by the abort handler in order to + determine whether it is should use longjmp to get back into this function. + That is, the abort handler determines if it is on the same stack as this function + and then jumps back into this function. + */ + g_bInGetJavaVM = 1; + jint err; + JavaVM * pJavaVM; + memset( jmp_jvm_abort, 0, sizeof(jmp_jvm_abort)); + int jmpval= setjmp( jmp_jvm_abort ); + /* If jmpval is not "0" then this point was reached by a longjmp in the + abort_handler, which was called indirectly by JNI_CreateVM. + */ + if( jmpval == 0) + { + //returns negative number on failure + err= pCreateJavaVM(&pJavaVM, ppEnv, &vm_args); + g_bInGetJavaVM = 0; + } + else + // set err to a positive number, so as or recognize that an abort (longjmp) + //occurred + err= 1; + + if(err != 0) + { + rtl::OUString message; + if( err < 0) + { + fprintf(stderr,"Can not create Java Virtual Machine"); + errcode = JFW_PLUGIN_E_ERROR; + } + else if( err > 0) + { + fprintf(stderr,"Can not create JavaVirtualMachine, abort handler was called"); + errcode = JFW_PLUGIN_E_ERROR; + } + } + else + { + *ppVm = pJavaVM; + } + + + return errcode; +} + + + + + diff --git a/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.map b/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.map new file mode 100644 index 000000000000..9c02ac5d3a1d --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/sunjavaplugin.map @@ -0,0 +1,8 @@ +UDK_3_0_0 { + global: + getAllJavaInfos; + getJavaInfoByPath; + startJavaVirtualMachine; + local: + *; +}; diff --git a/jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx b/jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx new file mode 100644 index 000000000000..bc7f15d545d5 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx @@ -0,0 +1,563 @@ +/************************************************************************* + * + * $RCSfile: sunversion.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jl $ $Date: 2004-04-19 15:36:26 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include "sunversion.hxx" +#include "osl/thread.h" +#include "osl/process.h" +#include "osl/security.hxx" +#include <string.h> +#include <ctype.h> + +using namespace rtl; +using namespace osl; +//using namespace JavaInfo; +using stoc_javadetect::SunVersion; +//using jvmaccess::JavaInfo::Impl; + +namespace stoc_javadetect { + +//extern OUString ::Impl::usPathDelim(); +#define OUSTR( x ) ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( x )) +#ifdef SUNVERSION_SELFTEST +class SelfTest +{ +public: + SelfTest(); +} test; +#endif + + +SunVersion::SunVersion(): m_nUpdateSpecial(0), + m_preRelease(Rel_NONE), + m_bValid(false) +{ + memset(m_arVersionParts, 0, sizeof(m_arVersionParts)); +} + +SunVersion::SunVersion(const rtl::OUString &usVer): + m_nUpdateSpecial(0), m_preRelease(Rel_NONE), + usVersion(usVer) +{ + memset(m_arVersionParts, 0, sizeof(m_arVersionParts)); + rtl::OString sVersion= rtl::OUStringToOString(usVer, osl_getThreadTextEncoding()); + m_bValid = init(sVersion.getStr()); +} +SunVersion::SunVersion(const char * szVer): + m_nUpdateSpecial(0), m_preRelease(Rel_NONE) +{ + memset(m_arVersionParts, 0, sizeof(m_arVersionParts)); + m_bValid = init(szVer); + usVersion= rtl::OUString(szVer,strlen(szVer),osl_getThreadTextEncoding()); +} + + +/**Format major.minor.maintainance_update + */ +bool SunVersion::init(const char *szVersion) +{ + if ( ! szVersion || strlen(szVersion) == 0) + return false; + + //first get the major,minor,maintainance + const char * pLast = szVersion; + const char * pCur = szVersion; + //pEnd point to the position after the last character + const char * pEnd = szVersion + strlen(szVersion); + // 0 = major, 1 = minor, 2 = maintainance, 3 = update + int nPart = 0; + // position within part beginning with 0 + int nPartPos = 0; + char buf[128]; + + //char must me a number 0 - 999 and no leading + char cCur = *pCur; + while (1) + { + if (pCur < pEnd && isdigit(*pCur)) + { + if (pCur < pEnd) + pCur ++; + nPartPos ++; + } + //if correct separator then form integer + else if ( + ! (nPartPos == 0) // prevents: ".4.1", "..1", part must start with digit + && ( + //seperators after maintainance (1.4.1_01, 1.4.1-beta, or1.4.1 + (pCur == pEnd || *pCur == '_' || *pCur == '-') + && (nPart == 2 ) + || + //separators between major-minor and minor-maintainance + (nPart < 2 && *pCur == '.') ) + && ( + //prevent 1.4.0. 1.4.0- + pCur + 1 == pEnd ? isdigit(*(pCur)) : 1) ) + { + int len = pCur - pLast; + if (len >= 127) + return false; + + strncpy(buf, pLast, len); + buf[len] = 0; + pCur ++; + pLast = pCur; + + m_arVersionParts[nPart] = atoi(buf); + nPart ++; + nPartPos = 0; + if (nPart == 3) + break; + + //check next character + if (! ( (pCur < pEnd) + && ( (nPart < 3) && isdigit(*pCur)))) //(*pCur >= 48 && *pCur <=57)))) + return false; + } + else + { + return false; + } + } + if (pCur >= pEnd) + return true; + //We have now 1.4.1. This can be followed by _01, -beta, etc. + // _01 (update) According to docu must not be followed by any other + //characters, but on Solaris 9 we have a 1.4.1_01a!! + if (* (pCur - 1) == '_') + {// _01, _02 + // update is the last part _01, _01a, part 0 is the digits parts and 1 the trailing alpha + int nUpdatePart = 0; + while (1) + { + if (pCur < pEnd && isdigit(*pCur)) + { + if (pCur < pEnd) + pCur ++; + // nPartPos ++; + } + else if (nUpdatePart == 0 && (pCur == pEnd || isalpha(*pCur))) + { + int len = pCur - pLast; + if (len >= 127) + return false; + + strncpy(buf, pLast, len); + buf[len] = 0; + m_arVersionParts[nPart] = atoi(buf); + nUpdatePart ++; + + //_01a, only on character at last position + if (pCur < pEnd && isalpha(*pCur)) + { + //this must be the last char + if (! (pCur + 1 == pEnd)) + return false; + if (isupper(*pCur)) + m_nUpdateSpecial = *pCur + 0x20; //make lowercase + else + m_nUpdateSpecial = *pCur; + + } + break; + } + else + { + return false; + } + } + } + else if (*(pCur - 1) == '-') + { + if( ! strcmp(pCur,"ea")) + m_preRelease = Rel_EA; + else if( ! strcmp(pCur,"ea1")) + m_preRelease = Rel_EA1; + else if( ! strcmp(pCur,"ea2")) + m_preRelease = Rel_EA2; + else if ( ! strcmp(pCur,"beta")) + m_preRelease = Rel_BETA; + else if ( ! strcmp(pCur,"beta1")) + m_preRelease = Rel_BETA1; + else if ( ! strcmp(pCur,"beta2")) + m_preRelease = Rel_BETA2; + else if (! strcmp(pCur, "rc")) + m_preRelease = Rel_RC; + else if (! strcmp(pCur, "rc1")) + m_preRelease = Rel_RC1; + else if (! strcmp(pCur, "rc2")) + m_preRelease = Rel_RC2; +#if defined FREEBSD + // #i21615#: FreeBSD adds p[1-8] to their JDK port. + else if (! strcmp(pCur, "p8")) + m_preRelease = Rel_BETA; + else if (! strcmp(pCur, "p7")) + m_preRelease = Rel_BETA; + else if (! strcmp(pCur, "p6")) + m_preRelease = Rel_BETA; + else if (! strcmp(pCur, "p5")) + m_preRelease = Rel_BETA; + else if (! strcmp(pCur, "p4")) + m_preRelease = Rel_BETA; + else if (! strcmp(pCur, "p3")) + m_preRelease = Rel_BETA; + else if (! strcmp(pCur, "p2")) + m_preRelease = Rel_BETA; + else if (! strcmp(pCur, "p1")) + m_preRelease = Rel_BETA; +#endif + else + return false; + } + else + { + return false; + } + return true; +} + +SunVersion::~SunVersion() +{ +// delete[] strVersion; +} + +/* Examples: + a) 1.0 < 1.1 + b) 1.0 < 1.0.0 + c) 1.0 < 1.0_00 + + returns false if both values are equal +*/ +bool SunVersion::operator > (const SunVersion& ver) const +{ + if( &ver == this) + return false; + + bool ret= false; + bool bDone = false; + + if (m_preRelease == ver.m_preRelease) + { + //compare major.minor.maintainance + for( int i= 0; i < 4; i ++) + { + // 1.4 > 1.3 + if(m_arVersionParts[i] > ver.m_arVersionParts[i]) + { + ret= true; + bDone = true; + break; + } + else if (m_arVersionParts[i] < ver.m_arVersionParts[i]) + { + bDone = true; + break; + } + } + //major.minor.maintainance_update are equal. test for a trailing char + if (bDone == false + && m_nUpdateSpecial > ver.m_nUpdateSpecial) + ret = true; + } + else if (m_preRelease == Rel_NONE && ver.m_preRelease > Rel_NONE) + {// a pre release is always minor to a relesase version: + // 1.3.1 > 1.4.0-beta + ret = true; + } + else if (m_preRelease > Rel_NONE && ver.m_preRelease == Rel_NONE) + { + ret = false; + } + else if(m_preRelease > ver.m_preRelease) + { + ret = true; + } + else + ret = false; // m_preRelease < ver.m_preRelease + + return ret; +} + +bool SunVersion::operator < (const SunVersion& ver) const +{ + return (! operator > (ver)) && (! operator == (ver)); +} + +bool SunVersion::operator == (const SunVersion& ver) const +{ + bool bRet= true; + for(int i= 0; i < 4; i++) + { + if( m_arVersionParts[i] != ver.m_arVersionParts[i]) + { + bRet= false; + break; + } + } + bRet = m_nUpdateSpecial == ver.m_nUpdateSpecial && bRet; + bRet = m_preRelease == ver.m_preRelease && bRet; + return bRet; +} + +SunVersion::operator bool() +{ + return m_bValid; +} + +SunVersion initVersion(const OUString& usJavaHomeArg) +{ + OSL_ASSERT( usJavaHomeArg.getLength() > 0); + SunVersion ret; + //create the string to the java executable +#if defined WNT + OUString usJava(RTL_CONSTASCII_USTRINGPARAM + ("java.exe")); +#else // WNT + OUString usJava(RTL_CONSTASCII_USTRINGPARAM + ("java")); +#endif // WNT + usJava= usJavaHomeArg + OUSTR("/bin/") + usJava; + OUString usStartDir; + OUString argument(RTL_CONSTASCII_USTRINGPARAM("-version")); + oslProcess javaProcess= 0; + oslFileHandle fileOut= 0; + oslFileHandle fileErr= 0; + + oslProcessError procErr = + osl_executeProcess_WithRedirectedIO( usJava.pData,//usExe.pData, + &argument.pData, //rtl_uString *strArguments[], + 1, //sal_uInt32 nArguments, + osl_Process_HIDDEN, //oslProcessOption Options, + Security().getHandle(), //oslSecurity Security, + usStartDir.pData,//usStartDir.pData,//usWorkDir.pData, //rtl_uString *strWorkDir, + NULL, //rtl_uString *strEnvironment[], + 0, // sal_uInt32 nEnvironmentVars, + &javaProcess, //oslProcess *pProcess, + NULL,//oslFileHandle *pChildInputWrite, + &fileOut,//oslFileHandle *pChildOutputRead, + &fileErr);//oslFileHandle *pChildErrorRead); + + if( procErr == osl_Process_E_None) + { + const sal_Int32 BUF_SIZE= 512; + sal_Char buf[BUF_SIZE]; + memset(buf, 0, BUF_SIZE); + sal_uInt64 read= 0; + TimeValue waitMax= {5 ,0}; + if(osl_Process_E_None == osl_joinProcessWithTimeout(javaProcess, &waitMax)) + { + //Read the output from stderr + if(osl_readFile(fileErr, &buf, BUF_SIZE, &read) == osl_File_E_None) + { + ret = getVersionFromBuf(buf, BUF_SIZE); + } + // If we have no version yet try stdout + if( ! ret) + { + if(osl_readFile(fileOut, &buf, BUF_SIZE - 1, &read) == osl_File_E_None) + { + ret = getVersionFromBuf(buf, BUF_SIZE - 1); + } + } + } + } + osl_closeFile(fileErr); + osl_closeFile(fileOut); + return ret; +} + +/** java -version has an output that reads: java version "1.4.0" in the first line + @param arg + max size of buffer pBuf + */ +SunVersion getVersionFromBuf( const sal_Char *pBuf, sal_Int32 size) +{ + // look for the string "version" + sal_Int32 i= rtl_str_indexOfStr_WithLength( (const sal_Char*) pBuf, + size, + RTL_CONSTASCII_STRINGPARAM( + "version")); + if(i == -1) + return SunVersion(pBuf); + + sal_Char* pEnd= (sal_Char*)pBuf + size - 1; + pBuf += i + RTL_CONSTASCII_LENGTH("version"); + // skip tabs an spaces + while (pBuf != pEnd && (*pBuf == '\t' || *pBuf == ' ')) + ++pBuf; + // next char " ? then move one forward + if (pBuf != pEnd && *pBuf == '"') + ++pBuf; + // now we have the beginning of the version string. + // search for the end of the string indicated by white space or a character + // other than '.','_' or 0 ..9 + sal_Char *pEndVer= (sal_Char*) pBuf; + while(pEndVer != pEnd && + (*pEndVer != '\t' + && *pEndVer != ' ' + && *pEndVer != '\n' + && *pEndVer != '\"')) + pEndVer++; + // found the end, create the version string + sal_Int32 sizeVer= pEndVer - pBuf + 1; + char *szVersion= new char[sizeVer]; + strncpy(szVersion, pBuf, sizeVer); + szVersion[sizeVer - 1]= 0; + SunVersion oVersion(szVersion); + delete[] szVersion; + + return oVersion; +} + +#ifdef SUNVERSION_SELFTEST +SelfTest::SelfTest() +{ + bool bRet = true; + + char * versions[] = {"1.4.0", "1.4.1", "1.0.0", "10.0.0", "10.10.0", + "10.2.2", "10.10.0", "10.10.10", "111.0.999", + "1.4.1_01", "9.90.99_09", "1.4.1_99", + "1.4.1_00a", "1.4.0_01z", "1.4.1_99A", + "1.4.1-ea", "1.4.1-beta", "1.4.1-rc1"}; + char * badVersions[] = {".4.0", "..1", "", "10.0", "10.10.0.", "10.10.0-", "10.10.0.", + "10.2-2", "10_10.0", "10..10","10.10", "a.0.999", + "1.4b.1_01", "9.90.-99_09", "1.4.1_99-", + "1.4.1_00a2", "1.4.0_z01z", "1.4.1__99A", + "1.4.1-1ea"}; + char * orderedVer[] = { "1.3.1-ea", "1.3.1-beta", "1.3.1-rc1", + "1.3.1", "1.3.1_00a", "1.3.1_01", "1.3.1_01a", "1.3.1_01b", + "1.3.2", "1.4.0", "2.0.0"}; + + size_t num = sizeof (versions) / sizeof(char*); + size_t numBad = sizeof (badVersions) / sizeof(char*); + size_t numOrdered = sizeof (orderedVer) / sizeof(char*); + //parsing test (positive) + for (int i = 0; i < num; i++) + { + SunVersion ver(versions[i]); + if ( ! ver) + { + bRet = false; + break; + } + } + OSL_ENSURE(bRet, "SunVersion selftest failed"); + //Parsing test (negative) + for ( i = 0; i < numBad; i++) + { + SunVersion ver(badVersions[i]); + if (ver) + { + bRet = false; + break; + } + } + OSL_ENSURE(bRet, "SunVersion selftest failed"); + + // Ordering test + bRet = true; + int j = 0; + for (i = 0; i < numOrdered; i ++) + { + SunVersion curVer(orderedVer[i]); + if ( ! curVer) + { + bRet = false; + break; + } + for (j = 0; j < numOrdered; j++) + { + SunVersion compVer(orderedVer[j]); + if (i < j) + { + if ( !(curVer < compVer)) + { + bRet = false; + break; + } + } + else if ( i == j) + { + if (! (curVer == compVer + && ! (curVer > compVer) + && ! (curVer < compVer))) + { + bRet = false; + break; + } + } + else if (i > j) + { + if ( !(curVer > compVer)) + { + bRet = false; + break; + } + } + } + if ( ! bRet) + break; + } + OSL_ENSURE(bRet, "SunVersion self test failed"); + +} +#endif + +} diff --git a/jvmfwk/plugins/sunmajor/pluginlib/sunversion.hxx b/jvmfwk/plugins/sunmajor/pluginlib/sunversion.hxx new file mode 100644 index 000000000000..57642d0191a4 --- /dev/null +++ b/jvmfwk/plugins/sunmajor/pluginlib/sunversion.hxx @@ -0,0 +1,151 @@ +/************************************************************************* + * + * $RCSfile: sunversion.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jl $ $Date: 2004-04-19 15:36:59 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#if !defined INCLUDED_JVMACCESS_SUNVERSION_HXX +#define INCLUDED_JVMACCESS_SUNVERSION_HXX + +#include "rtl/ustring.hxx" + +namespace stoc_javadetect { +// Define SUNVERSION_SELFTEST to run a test when this lib is loaded +//#define SUNVERSION_SELFTEST + +/* SunVersion is used to compare java versions based on a string, as taken + from the registry. The strings look like "1.3", "1.3.1", "1.3.1_02" etc. + Versions such as "1.4.1_01a" are allowed although this is not specified. + 1.4.1_01 < 1.4.1_01a < 1.4.1_01b < 1.4.1_02 + Pre - release versions, such as 1.4.1-ea, 1.4.1-beta, 1.4.1-rc are recognized, + but are treated as minor to release versions: + 1.4.0 > 1.4.2-beta + Pre releases relate this way + 1.4.1-ea < 1.4.1-beta < 1.4.1-rc1 + + An object acts as holder for the version string. That string may be present + even if the version could not be parsed. Then the version may not be compatible + to a SUN Java version. + + An invalid object, that is, operator bool returns false, will always be + the lower version in a comparison. If two invalid objects are compared + then they are considered equal. + + To test if the version is ok, that is this object can be compared to others, + use the bool conversion operator. + */ +class SunVersion +{ +protected: + + enum PreRelease + { + Rel_NONE, + Rel_EA, + Rel_EA1, + Rel_EA2, + Rel_BETA, + Rel_BETA1, + Rel_BETA2, + Rel_RC, + Rel_RC1, + Rel_RC2 + }; + + //contains major,minor,micro,update + int m_arVersionParts[4]; + // The update can be followed by a char, e.g. 1.4.1_01a + char m_nUpdateSpecial; + + PreRelease m_preRelease; +public: + SunVersion(); + SunVersion(const char * szVer); + SunVersion(const rtl::OUString& usVer); + ~SunVersion(); + + bool operator > (const SunVersion& ver) const; + bool operator < (const SunVersion& ver) const; + bool operator == (const SunVersion& ver) const; + + /** Test if the version is compatible tu SUN's versioning scheme + */ + operator bool (); + + /** Will always contain a value if the object has been constructed with + a version string. + */ + rtl::OUString usVersion; + +protected: + bool init(const char * szVer); + + bool m_bValid; +}; + +/** + @param usJavaHome + File URL of the java installation directory. +*/ +SunVersion initVersion(const rtl::OUString& usJavaHome); + +SunVersion getVersionFromBuf(const sal_Char *pBuf, sal_Int32 sizeBuf); + +} + +#endif // INCLUDED_JVMACCESS_SUNVERSION_HXX |