LCOV - code coverage report
Current view: top level - jvmfwk/plugins/sunmajor/pluginlib - util.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 249 436 57.1 %
Date: 2015-06-13 12:38:46 Functions: 27 33 81.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <config_features.h>
      21             : #include <config_folders.h>
      22             : 
      23             : #include "util.hxx"
      24             : 
      25             : #include "osl/process.h"
      26             : #include "osl/security.hxx"
      27             : #include "osl/file.hxx"
      28             : #include "osl/module.hxx"
      29             : #include <osl/diagnose.h>
      30             : #include <osl/getglobalmutex.hxx>
      31             : #include "rtl/byteseq.hxx"
      32             : #include "rtl/ustrbuf.hxx"
      33             : #include "rtl/instance.hxx"
      34             : #include "salhelper/linkhelper.hxx"
      35             : #include "salhelper/thread.hxx"
      36             : #include "boost/noncopyable.hpp"
      37             : #include "boost/scoped_array.hpp"
      38             : #include "com/sun/star/uno/Sequence.hxx"
      39             : #include <utility>
      40             : #include <algorithm>
      41             : #include <map>
      42             : 
      43             : #if defined WNT
      44             : #if defined _MSC_VER
      45             : #pragma warning(push, 1)
      46             : #endif
      47             : #include <windows.h>
      48             : #if defined _MSC_VER
      49             : #pragma warning(pop)
      50             : #endif
      51             : #endif
      52             : #include <string.h>
      53             : 
      54             : #include "sunjre.hxx"
      55             : #include "vendorlist.hxx"
      56             : #include "diagnostics.h"
      57             : 
      58             : using namespace osl;
      59             : using namespace std;
      60             : 
      61             : using ::rtl::Reference;
      62             : 
      63             : #ifdef WNT
      64             : #define HKEY_SUN_JRE L"Software\\JavaSoft\\Java Runtime Environment"
      65             : #define HKEY_SUN_SDK L"Software\\JavaSoft\\Java Development Kit"
      66             : #endif
      67             : 
      68             : #ifdef UNX
      69             : #if !(defined MACOSX && defined X86_64)
      70             : namespace {
      71             : char const *g_arJavaNames[] = {
      72             :     "",
      73             :     "j2re",
      74             :     "j2se",
      75             :     "j2sdk",
      76             :     "jdk",
      77             :     "jre",
      78             :     "java",
      79             :     "Home",
      80             :     "IBMJava2-ppc-142"
      81             : };
      82             : /* These are directory names which could contain multiple java installations.
      83             :  */
      84             : char const *g_arCollectDirs[] = {
      85             :     "",
      86             : #ifndef JVM_ONE_PATH_CHECK
      87             :     "j2re/",
      88             :     "j2se/",
      89             :     "j2sdk/",
      90             :     "jdk/",
      91             :     "jre/",
      92             :     "java/",
      93             : #endif
      94             :     "jvm/"
      95             : };
      96             : 
      97             : /* These are directories in which a java installation is
      98             :    looked for.
      99             : */
     100             : char const *g_arSearchPaths[] = {
     101             : #ifdef MACOSX
     102             :     "",
     103             :     "Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin",
     104             :     "System/Library/Frameworks/JavaVM.framework/Versions/1.4.2/"
     105             : #else
     106             : #ifndef JVM_ONE_PATH_CHECK
     107             :     "",
     108             :     "usr/",
     109             :     "usr/local/",
     110             :     "usr/local/IBMJava2-ppc-142",
     111             :     "usr/local/j2sdk1.3.1",
     112             : #ifdef X86_64
     113             :     "usr/lib64/",
     114             : #endif
     115             :     "usr/lib/",
     116             :     "usr/bin/"
     117             : #else
     118             :     JVM_ONE_PATH_CHECK
     119             : #endif
     120             : #endif
     121             : };
     122             : }
     123             : #endif
     124             : #endif //  UNX
     125             : 
     126             : namespace jfw_plugin
     127             : {
     128             : extern VendorSupportMapEntry gVendorMap[];
     129             : 
     130             : #if defined WNT
     131             : bool getSDKInfoFromRegistry(vector<OUString> & vecHome);
     132             : bool getJREInfoFromRegistry(vector<OUString>& vecJavaHome);
     133             : #endif
     134             : 
     135             : bool decodeOutput(const OString& s, OUString* out);
     136             : 
     137             : 
     138             : 
     139             : namespace
     140             : {
     141             : 
     142           4 : bool addJREInfo(
     143             :     rtl::Reference<VendorBase> const & info,
     144             :     std::vector<rtl::Reference<VendorBase>> & infos)
     145             : {
     146             :     auto i(
     147             :         std::find_if(
     148           4 :             infos.begin(), infos.end(), InfoFindSame(info->getHome())));
     149           4 :     if (i == infos.end()) {
     150           4 :         infos.push_back(info);
     151           4 :         return true;
     152             :     } else {
     153           0 :         return false;
     154             :     }
     155             : }
     156             : 
     157           4 : bool getAndAddJREInfoByPath(
     158             :     const OUString& path,
     159             :     std::vector<rtl::Reference<VendorBase> > & allInfos,
     160             :     std::vector<rtl::Reference<VendorBase> > & addedInfos)
     161             : {
     162           4 :     rtl::Reference<VendorBase> aInfo = getJREInfoByPath(path);
     163           4 :     if (aInfo.is()) {
     164           4 :         if (addJREInfo(aInfo, allInfos)) {
     165           4 :             addedInfos.push_back(aInfo);
     166             :         }
     167           4 :         return true;
     168             :     } else {
     169           0 :         return false;
     170           4 :     }
     171             : }
     172             : 
     173          77 :     OUString getLibraryLocation()
     174             :     {
     175          77 :         OUString libraryFileUrl;
     176          77 :         OSL_VERIFY(osl::Module::getUrlFromAddress(reinterpret_cast<void *>(getLibraryLocation), libraryFileUrl));
     177          77 :         return getDirFromFile(libraryFileUrl);
     178             :     }
     179             : 
     180             :     struct InitBootstrap
     181             :     {
     182          77 :         rtl::Bootstrap * operator()(const OUString& sIni)
     183             :         {
     184          77 :             static rtl::Bootstrap aInstance(sIni);
     185          77 :             return & aInstance;
     186             : 
     187             :         }
     188             :    };
     189             : 
     190             :    struct InitBootstrapData
     191             :    {
     192          77 :        OUString const & operator()()
     193             :        {
     194          77 :            static OUString sIni;
     195          77 :             OUStringBuffer buf( 255);
     196          77 :             buf.append( getLibraryLocation());
     197             : #ifdef MACOSX
     198             :             buf.appendAscii( "/../" LIBO_ETC_FOLDER );
     199             : #endif
     200          77 :             buf.appendAscii( SAL_CONFIGFILE("/sunjavaplugin") );
     201          77 :             sIni = buf.makeStringAndClear();
     202             :             JFW_TRACE2("Using configuration file " << sIni);
     203          77 :             return sIni;
     204             :         }
     205             :    };
     206             : }
     207             : 
     208         154 : rtl::Bootstrap * getBootstrap()
     209             : {
     210             :     return rtl_Instance< rtl::Bootstrap, InitBootstrap,
     211             :         ::osl::MutexGuard, ::osl::GetGlobalMutex,
     212             :         OUString, InitBootstrapData >::create(
     213         154 :             InitBootstrap(), ::osl::GetGlobalMutex(), InitBootstrapData());
     214             : }
     215             : 
     216             : 
     217             : 
     218             : 
     219             : class FileHandleGuard: private boost::noncopyable
     220             : {
     221             : public:
     222         154 :     inline FileHandleGuard(oslFileHandle & rHandle):
     223         154 :         m_rHandle(rHandle) {}
     224             : 
     225             :     inline ~FileHandleGuard();
     226             : 
     227      339212 :     inline oslFileHandle & getHandle() { return m_rHandle; }
     228             : 
     229             : private:
     230             :     oslFileHandle & m_rHandle;
     231             : };
     232             : 
     233         154 : inline FileHandleGuard::~FileHandleGuard()
     234             : {
     235         154 :     if (m_rHandle != 0)
     236             :     {
     237         154 :         if (osl_closeFile(m_rHandle) != osl_File_E_None)
     238             :         {
     239             :             OSL_FAIL("unexpected situation");
     240             :         }
     241             :     }
     242         154 : }
     243             : 
     244             : 
     245          77 : class FileHandleReader
     246             : {
     247             : public:
     248             :     enum Result
     249             :     {
     250             :         RESULT_OK,
     251             :         RESULT_EOF,
     252             :         RESULT_ERROR
     253             :     };
     254             : 
     255          77 :     inline FileHandleReader(oslFileHandle & rHandle):
     256          77 :         m_aGuard(rHandle), m_nSize(0), m_nIndex(0), m_bLf(false) {}
     257             : 
     258             :     Result readLine(OString * pLine);
     259             : 
     260             : private:
     261             :     enum { BUFFER_SIZE = 1024 };
     262             : 
     263             :     sal_Char m_aBuffer[BUFFER_SIZE];
     264             :     FileHandleGuard m_aGuard;
     265             :     int m_nSize;
     266             :     int m_nIndex;
     267             :     bool m_bLf;
     268             : };
     269             : 
     270             : FileHandleReader::Result
     271        4004 : FileHandleReader::readLine(OString * pLine)
     272             : {
     273             :     OSL_ENSURE(pLine, "specification violation");
     274             : 
     275      339154 :     for (bool bEof = true;; bEof = false)
     276             :     {
     277      339154 :         if (m_nIndex == m_nSize)
     278             :         {
     279      339135 :             sal_uInt64 nRead = 0;
     280      339135 :             switch (osl_readFile(
     281      339135 :                         m_aGuard.getHandle(), m_aBuffer, sizeof(m_aBuffer), &nRead))
     282             :             {
     283             :             case osl_File_E_PIPE: //HACK! for windows
     284           0 :                 nRead = 0;
     285             :                 //fall-through
     286             :             case osl_File_E_None:
     287      339135 :                 if (nRead == 0)
     288             :                 {
     289          77 :                     m_bLf = false;
     290         154 :                     return bEof ? RESULT_EOF : RESULT_OK;
     291             :                 }
     292      339058 :                 m_nIndex = 0;
     293      339058 :                 m_nSize = static_cast< int >(nRead);
     294      339058 :                 break;
     295             :             case osl_File_E_INTR:
     296           0 :                 continue;
     297             : 
     298             :             default:
     299           0 :                 return RESULT_ERROR;
     300             :             }
     301             :         }
     302             : 
     303      339077 :         if (m_bLf && m_aBuffer[m_nIndex] == 0x0A)
     304           0 :             ++m_nIndex;
     305      339077 :         m_bLf = false;
     306             : 
     307      339077 :         int nStart = m_nIndex;
     308     1284794 :         while (m_nIndex != m_nSize)
     309      610567 :             switch (m_aBuffer[m_nIndex++])
     310             :             {
     311             :             case 0x0D:
     312           0 :                 m_bLf = true;
     313             :             case 0x0A:
     314        7854 :                 *pLine += OString(m_aBuffer + nStart,
     315        7854 :                                        m_nIndex - 1 - nStart);
     316             :                     //TODO! check for overflow, and not very efficient
     317        3927 :                 return RESULT_OK;
     318             :             }
     319             : 
     320      335150 :         *pLine += OString(m_aBuffer + nStart, m_nIndex - nStart);
     321             :             //TODO! check for overflow, and not very efficient
     322      335150 :     }
     323             : }
     324             : 
     325             : class AsynchReader: public salhelper::Thread
     326             : {
     327             :     size_t  m_nDataSize;
     328             :     boost::scoped_array<sal_Char> m_arData;
     329             : 
     330             :     bool m_bError;
     331             :     bool m_bDone;
     332             :     FileHandleGuard m_aGuard;
     333             : 
     334         154 :     virtual ~AsynchReader() {}
     335             : 
     336             :     void execute() SAL_OVERRIDE;
     337             : public:
     338             : 
     339             :     AsynchReader(oslFileHandle & rHandle);
     340             : 
     341             :     /** only call this function after this thread has finished.
     342             : 
     343             :         That is, call join on this instance and then call getData.
     344             : 
     345             :      */
     346             :     OString getData();
     347             : };
     348             : 
     349          77 : AsynchReader::AsynchReader(oslFileHandle & rHandle):
     350             :     Thread("jvmfwkAsyncReader"), m_nDataSize(0), m_bError(false),
     351          77 :     m_bDone(false), m_aGuard(rHandle)
     352             : {
     353          77 : }
     354             : 
     355           0 : OString AsynchReader::getData()
     356             : {
     357           0 :     return OString(m_arData.get(), m_nDataSize);
     358             : }
     359             : 
     360          77 : void AsynchReader::execute()
     361             : {
     362          77 :     const sal_uInt64 BUFFER_SIZE = 4096;
     363             :     sal_Char aBuffer[BUFFER_SIZE];
     364             :     while (true)
     365             :     {
     366             :         sal_uInt64 nRead;
     367             :         //the function blocks until something could be read or the pipe closed.
     368          77 :         switch (osl_readFile(
     369          77 :                     m_aGuard.getHandle(), aBuffer, BUFFER_SIZE, &nRead))
     370             :         {
     371             :         case osl_File_E_PIPE: //HACK! for windows
     372           0 :             nRead = 0;
     373             :         case osl_File_E_None:
     374          77 :             break;
     375             :         default:
     376           0 :             m_bError = true;
     377          77 :             return;
     378             :         }
     379             : 
     380          77 :         if (nRead == 0)
     381             :         {
     382          77 :             m_bDone = true;
     383         154 :             break;
     384             :         }
     385           0 :         else if (nRead <= BUFFER_SIZE)
     386             :         {
     387             :             //Save the data we have in m_arData into a temporary array
     388           0 :             boost::scoped_array<sal_Char> arTmp( new sal_Char[m_nDataSize]);
     389           0 :             memcpy(arTmp.get(), m_arData.get(), m_nDataSize);
     390             :             //Enlarge m_arData to hold the newly read data
     391           0 :             m_arData.reset(new sal_Char[(size_t)(m_nDataSize + nRead)]);
     392             :             //Copy back the data that was already in m_arData
     393           0 :             memcpy(m_arData.get(), arTmp.get(), m_nDataSize);
     394             :             //Add the newly read data to m_arData
     395           0 :             memcpy(m_arData.get() + m_nDataSize, aBuffer, (size_t) nRead);
     396           0 :             m_nDataSize += (size_t) nRead;
     397             :         }
     398           0 :     }
     399             : }
     400             : 
     401         154 : static bool isEnvVarSetToOne(const OUString &aVar)
     402             : {
     403         154 :     OUString aValue;
     404         154 :     getBootstrap()->getFrom(aVar, aValue);
     405         154 :     return aValue == "1";
     406             : }
     407             : 
     408          77 : bool getJavaProps(const OUString & exePath,
     409             : #ifdef JVM_ONE_PATH_CHECK
     410             :                   const OUString & homePath,
     411             : #endif
     412             :                   std::vector<std::pair<OUString, OUString> >& props,
     413             :                   bool * bProcessRun)
     414             : {
     415          77 :     bool ret = false;
     416             : 
     417             :     OSL_ASSERT(!exePath.isEmpty());
     418          77 :     OUString usStartDir;
     419             :     //We need to set the CLASSPATH in case the office is started from
     420             :     //a different directory. The JREProperties.class is expected to reside
     421             :     //next to the plugin, except on OS X where it is in ../Resources/java relative
     422             :     //to the plugin.
     423         154 :     OUString sThisLib;
     424          77 :     if (osl_getModuleURLFromAddress(reinterpret_cast<void *>(&getJavaProps),
     425          77 :                                     & sThisLib.pData) == sal_False)
     426             :     {
     427           0 :         return false;
     428             :     }
     429          77 :     sThisLib = getDirFromFile(sThisLib);
     430         154 :     OUString sClassPath;
     431          77 :     if (osl_getSystemPathFromFileURL(sThisLib.pData, & sClassPath.pData)
     432             :         != osl_File_E_None)
     433             :     {
     434           0 :         return false;
     435             :     }
     436             : 
     437             : #ifdef MACOSX
     438             :     if (sClassPath.endsWith("/"))
     439             :         sClassPath += "../Resources/java/";
     440             :     else
     441             :         sClassPath += "/../Resources/java";
     442             : #endif
     443             : 
     444             :     //check if we shall examine a Java for accessibility support
     445             :     //If the bootstrap variable is "1" then we pass the argument
     446             :     //"noaccessibility" to JREProperties.class. This will prevent
     447             :     //that it calls   java.awt.Toolkit.getDefaultToolkit();
     448          77 :     bool bNoAccessibility = isEnvVarSetToOne("JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY");
     449             : 
     450             :     //prepare the arguments
     451          77 :     sal_Int32 cArgs = 3;
     452         154 :     OUString arg1 = "-classpath";// + sClassPath;
     453         154 :     OUString arg2 = sClassPath;
     454         154 :     OUString arg3("JREProperties");
     455         154 :     OUString arg4 = "noaccessibility";
     456          77 :     rtl_uString *args[4] = {arg1.pData, arg2.pData, arg3.pData};
     457             : 
     458             : #ifdef UNX
     459             :     // Java is no longer required for a11y - we use atk directly.
     460          77 :     bNoAccessibility = !isEnvVarSetToOne("JFW_PLUGIN_FORCE_ACCESSIBILITY");
     461             : #endif
     462             : 
     463             :     // Only add the fourth param if the bootstrap parameter is set.
     464          77 :     if (bNoAccessibility)
     465             :     {
     466          77 :         args[3] = arg4.pData;
     467          77 :         cArgs = 4;
     468             :     }
     469             : 
     470          77 :     oslProcess javaProcess= 0;
     471          77 :     oslFileHandle fileOut= 0;
     472          77 :     oslFileHandle fileErr= 0;
     473             : 
     474         154 :     FileHandleReader stdoutReader(fileOut);
     475         154 :     rtl::Reference< AsynchReader > stderrReader(new AsynchReader(fileErr));
     476             : 
     477             :     JFW_TRACE2("Executing: " + exePath);
     478             :     oslProcessError procErr =
     479             :         osl_executeProcess_WithRedirectedIO( exePath.pData,//usExe.pData,
     480             :                                              args,
     481             :                                              cArgs,                 //sal_uInt32   nArguments,
     482             :                                              osl_Process_HIDDEN, //oslProcessOption Options,
     483             :                                              NULL, //oslSecurity Security,
     484             :                                              usStartDir.pData,//usStartDir.pData,//usWorkDir.pData, //rtl_uString *strWorkDir,
     485             :                                              NULL, //rtl_uString *strEnvironment[],
     486             :                                              0, //  sal_uInt32   nEnvironmentVars,
     487             :                                              &javaProcess, //oslProcess *pProcess,
     488             :                                              NULL,//oslFileHandle *pChildInputWrite,
     489             :                                              &fileOut,//oslFileHandle *pChildOutputRead,
     490          77 :                                              &fileErr);//oslFileHandle *pChildErrorRead);
     491             : 
     492          77 :     if( procErr != osl_Process_E_None)
     493             :     {
     494             :         JFW_TRACE2("Execution failed");
     495           0 :         *bProcessRun = false;
     496             :         SAL_WARN("jfw",
     497             :             "osl_executeProcess failed (" << ret << "): \"" << exePath << "\"");
     498           0 :         return ret;
     499             :     }
     500             :     else
     501             :     {
     502             :         JFW_TRACE2("Java executed successfully");
     503          77 :         *bProcessRun = true;
     504             :     }
     505             : 
     506             :     //Start asynchronous reading (different thread) of error stream
     507          77 :     stderrReader->launch();
     508             : 
     509             :     //Use this thread to read output stream
     510          77 :     FileHandleReader::Result rs = FileHandleReader::RESULT_OK;
     511             :     while (true)
     512             :     {
     513        4004 :         OString aLine;
     514        4004 :         rs = stdoutReader.readLine( & aLine);
     515        4004 :         if (rs != FileHandleReader::RESULT_OK)
     516          77 :             break;
     517        7854 :         OUString sLine;
     518        3927 :         if (!decodeOutput(aLine, &sLine))
     519           0 :             continue;
     520             :         JFW_TRACE2(" \"" << sLine << " \"");
     521        3927 :         sLine = sLine.trim();
     522        3927 :         if (sLine.isEmpty())
     523           0 :             continue;
     524             :         //The JREProperties class writes key value pairs, separated by '='
     525        3927 :         sal_Int32 index = sLine.indexOf('=', 0);
     526             :         OSL_ASSERT(index != -1);
     527        7854 :         OUString sKey = sLine.copy(0, index);
     528        7854 :         OUString sVal = sLine.copy(index + 1);
     529             : 
     530             : #ifdef JVM_ONE_PATH_CHECK
     531             :         //replace absolute path by linux distro link
     532             :         OUString sHomeProperty("java.home");
     533             :         if(sHomeProperty.equals(sKey))
     534             :         {
     535             :             sVal = homePath + "/jre";
     536             :         }
     537             : #endif
     538             : 
     539        3927 :         props.push_back(std::make_pair(sKey, sVal));
     540        3927 :     }
     541             : 
     542          77 :     if (rs != FileHandleReader::RESULT_ERROR && !props.empty())
     543          77 :         ret = true;
     544             : 
     545             :     //process error stream data
     546          77 :     stderrReader->join();
     547             :     JFW_TRACE2("Java wrote to stderr:\" "
     548             :                << stderrReader->getData().getStr() << " \"");
     549             : 
     550          77 :     TimeValue waitMax= {5 ,0};
     551          77 :     procErr = osl_joinProcessWithTimeout(javaProcess, &waitMax);
     552             :     OSL_ASSERT(procErr == osl_Process_E_None);
     553          77 :     osl_freeProcessHandle(javaProcess);
     554         154 :     return ret;
     555             : }
     556             : 
     557             : /* converts the properties printed by JREProperties.class into
     558             :     readable strings. The strings are encoded as integer values separated
     559             :     by spaces.
     560             :  */
     561        3927 : bool decodeOutput(const OString& s, OUString* out)
     562             : {
     563             :     OSL_ASSERT(out != 0);
     564        3927 :     OUStringBuffer buff(512);
     565        3927 :     sal_Int32 nIndex = 0;
     566      172674 :     do
     567             :     {
     568      172674 :         OString aToken = s.getToken( 0, ' ', nIndex );
     569      172674 :         if (!aToken.isEmpty())
     570             :         {
     571      606640 :             for (sal_Int32 i = 0; i < aToken.getLength(); ++i)
     572             :             {
     573      437893 :                 if (aToken[i] < '0' || aToken[i] > '9')
     574           0 :                     return false;
     575             :             }
     576      168747 :             sal_Unicode value = (sal_Unicode)(aToken.toInt32());
     577      168747 :             buff.append(value);
     578      172674 :         }
     579      172674 :     } while (nIndex >= 0);
     580             : 
     581        3927 :     *out = buff.makeStringAndClear();
     582        3927 :     return true;
     583             : }
     584             : 
     585             : 
     586             : #if defined WNT
     587             : void addJavaInfoFromWinReg(
     588             :     std::vector<rtl::Reference<VendorBase> > & allInfos,
     589             :     std::vector<rtl::Reference<VendorBase> > & addedInfos)
     590             : {
     591             :         // Get Java s from registry
     592             :     std::vector<OUString> vecJavaHome;
     593             :     if(getSDKInfoFromRegistry(vecJavaHome))
     594             :     {
     595             :         // create impl objects
     596             :         typedef std::vector<OUString>::iterator ItHome;
     597             :         for(ItHome it_home= vecJavaHome.begin(); it_home != vecJavaHome.end();
     598             :             ++it_home)
     599             :         {
     600             :             getAndAddJREInfoByPath(*it_home, allInfos, addedInfos);
     601             :         }
     602             :     }
     603             : 
     604             :     vecJavaHome.clear();
     605             :     if(getJREInfoFromRegistry(vecJavaHome))
     606             :     {
     607             :         typedef std::vector<OUString>::iterator ItHome;
     608             :         for(ItHome it_home= vecJavaHome.begin(); it_home != vecJavaHome.end();
     609             :             ++it_home)
     610             :         {
     611             :             getAndAddJREInfoByPath(*it_home, allInfos, addedInfos);
     612             :         }
     613             :    }
     614             : }
     615             : 
     616             : 
     617             : bool getJavaInfoFromRegistry(const wchar_t* szRegKey,
     618             :                              vector<OUString>& vecJavaHome)
     619             : {
     620             :     HKEY    hRoot;
     621             :     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_ENUMERATE_SUB_KEYS, &hRoot)
     622             :         == ERROR_SUCCESS)
     623             :     {
     624             :         DWORD dwIndex = 0;
     625             :         const DWORD BUFFSIZE = 1024;
     626             :         wchar_t bufVersion[BUFFSIZE];
     627             :         DWORD nNameLen = BUFFSIZE;
     628             :         FILETIME fileTime;
     629             :         nNameLen = sizeof(bufVersion);
     630             : 
     631             :         // Iterate over all subkeys of HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment
     632             :         while (RegEnumKeyExW(hRoot, dwIndex, bufVersion, &nNameLen, NULL, NULL, NULL, &fileTime) != ERROR_NO_MORE_ITEMS)
     633             :         {
     634             :             HKEY    hKey;
     635             :             // Open a Java Runtime Environment sub key, e.g. "1.4.0"
     636             :             if (RegOpenKeyExW(hRoot, bufVersion, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
     637             :             {
     638             :                 DWORD   dwType;
     639             :                 DWORD   dwTmpPathLen= 0;
     640             :                 // Get the path to the JavaHome every JRE entry
     641             :                 // Find out how long the string for JavaHome is and allocate memory to hold the path
     642             :                 if( RegQueryValueExW(hKey, L"JavaHome", 0, &dwType, NULL, &dwTmpPathLen)== ERROR_SUCCESS)
     643             :                 {
     644             :                     char* szTmpPath= (char *) malloc( dwTmpPathLen);
     645             :                     // Get the path for the runtime lib
     646             :                     if(RegQueryValueExW(hKey, L"JavaHome", 0, &dwType, (unsigned char*) szTmpPath, &dwTmpPathLen) == ERROR_SUCCESS)
     647             :                     {
     648             :                         // There can be several version entries referring with the same JavaHome,e.g 1.4 and 1.4.1
     649             :                         OUString usHome((sal_Unicode*) szTmpPath);
     650             :                         // check if there is already an entry with the same JavaHomeruntime lib
     651             :                         // if so, we use the one with the more accurate version
     652             :                         bool bAppend= true;
     653             :                         OUString usHomeUrl;
     654             :                         if (osl_getFileURLFromSystemPath(usHome.pData, & usHomeUrl.pData) ==
     655             :                             osl_File_E_None)
     656             :                         {
     657             :                             //iterate over the vector with java home strings
     658             :                             typedef vector<OUString>::iterator ItHome;
     659             :                             for(ItHome itHome= vecJavaHome.begin();
     660             :                                 itHome != vecJavaHome.end(); ++itHome)
     661             :                             {
     662             :                                 if(usHomeUrl.equals(*itHome))
     663             :                                 {
     664             :                                     bAppend= false;
     665             :                                     break;
     666             :                                 }
     667             :                             }
     668             :                             // Save the home dir
     669             :                             if(bAppend)
     670             :                             {
     671             :                                 vecJavaHome.push_back(usHomeUrl);
     672             :                             }
     673             :                         }
     674             :                     }
     675             :                     free( szTmpPath);
     676             :                     RegCloseKey(hKey);
     677             :                 }
     678             :             }
     679             :             dwIndex ++;
     680             :             nNameLen = BUFFSIZE;
     681             :         }
     682             :         RegCloseKey(hRoot);
     683             :     }
     684             :     return true;
     685             : }
     686             : 
     687             : 
     688             : 
     689             : bool getSDKInfoFromRegistry(vector<OUString> & vecHome)
     690             : {
     691             :     return getJavaInfoFromRegistry(HKEY_SUN_SDK, vecHome);
     692             : }
     693             : 
     694             : bool getJREInfoFromRegistry(vector<OUString>& vecJavaHome)
     695             : {
     696             :     return getJavaInfoFromRegistry(HKEY_SUN_JRE, vecJavaHome);
     697             : }
     698             : 
     699             : #endif // WNT
     700             : 
     701           0 : void bubbleSortVersion(vector<rtl::Reference<VendorBase> >& vec)
     702             : {
     703           0 :     if(vec.empty())
     704           0 :         return;
     705           0 :     int size= vec.size() - 1;
     706           0 :     int cIter= 0;
     707             :     // sort for version
     708           0 :     for(int i= 0; i < size; i++)
     709             :     {
     710           0 :         for(int j= size; j > 0 + cIter; j--)
     711             :         {
     712           0 :             rtl::Reference<VendorBase>& cur= vec.at(j);
     713           0 :             rtl::Reference<VendorBase>& next= vec.at(j-1);
     714             : 
     715           0 :             int nCmp = 0;
     716             :             // comparing invalid SunVersion s is possible, they will be less than a
     717             :             // valid version
     718             : 
     719             :             //check if version of current is recognized, by comparing it with itself
     720             :             try
     721             :             {
     722           0 :                 (void)cur->compareVersions(cur->getVersion());
     723             :             }
     724           0 :             catch (MalformedVersionException &)
     725             :             {
     726           0 :                 nCmp = -1; // current < next
     727             :             }
     728             :             //The version of cur is valid, now compare with the second version
     729           0 :             if (nCmp == 0)
     730             :             {
     731             :                 try
     732             :                 {
     733           0 :                     nCmp = cur->compareVersions(next->getVersion());
     734             :                 }
     735           0 :                 catch (MalformedVersionException & )
     736             :                 {
     737             :                     //The second version is invalid, therefore it regards less.
     738           0 :                     nCmp = 1;
     739             :                 }
     740             :             }
     741           0 :             if(nCmp == 1) // cur > next
     742             :             {
     743           0 :                 rtl::Reference<VendorBase> less = next;
     744           0 :                 vec.at(j-1)= cur;
     745           0 :                 vec.at(j)= less;
     746             :             }
     747             :         }
     748           0 :         ++cIter;
     749             :     }
     750             : }
     751             : 
     752             : 
     753           0 : void addJREInfoFromBinPath(
     754             :     const OUString& path, vector<rtl::Reference<VendorBase>> & allInfos,
     755             :     std::vector<rtl::Reference<VendorBase>> & addedInfos)
     756             : {
     757             :     // file:///c:/jre/bin
     758             :     //map:       jre/bin/java.exe
     759             : 
     760           0 :     for ( sal_Int32 pos = 0;
     761           0 :           gVendorMap[pos].sVendorName != NULL; ++pos )
     762             :     {
     763           0 :         vector<OUString> vecPaths;
     764           0 :         getJavaExePaths_func pFunc = gVendorMap[pos].getJavaFunc;
     765             : 
     766           0 :         int size = 0;
     767           0 :         char const* const* arExePaths = (*pFunc)(&size);
     768           0 :         vecPaths = getVectorFromCharArray(arExePaths, size);
     769             : 
     770             :         //make sure argument path does not end with '/'
     771           0 :         OUString sBinPath = path;
     772           0 :         if (path.endsWith("/"))
     773           0 :             sBinPath = path.copy(0, path.getLength() - 1);
     774             : 
     775             :         typedef vector<OUString>::const_iterator c_it;
     776           0 :         for (c_it i = vecPaths.begin(); i != vecPaths.end(); ++i)
     777             :         {
     778             :             //the map contains e.g. jre/bin/java.exe
     779             :             //get the directory where the executable is contained
     780           0 :             OUString sHome;
     781           0 :             sal_Int32 index = i->lastIndexOf('/');
     782           0 :             if (index == -1)
     783             :             {
     784             :                 //map contained only : "java.exe, then the argument
     785             :                 //path is already the home directory
     786           0 :                 sHome = sBinPath;
     787             :             }
     788             :             else
     789             :             {
     790             :                 // jre/bin/jre -> jre/bin
     791           0 :                 OUString sMapPath(i->getStr(), index);
     792           0 :                 index = sBinPath.lastIndexOf(sMapPath);
     793           0 :                 if (index != -1
     794           0 :                     && (index + sMapPath.getLength() == sBinPath.getLength())
     795           0 :                     && sBinPath[index - 1] == '/')
     796             :                 {
     797           0 :                     sHome = sBinPath.copy(index - 1);
     798           0 :                 }
     799             :             }
     800           0 :             if (!sHome.isEmpty()
     801           0 :                 && getAndAddJREInfoByPath(path, allInfos, addedInfos))
     802             :             {
     803           0 :                 return;
     804             :             }
     805           0 :         }
     806           0 :     }
     807             : }
     808             : 
     809           0 : vector<Reference<VendorBase> > addAllJREInfos(
     810             :     bool checkJavaHomeAndPath,
     811             :     std::vector<rtl::Reference<VendorBase>> & allInfos)
     812             : {
     813           0 :     vector<Reference<VendorBase> > addedInfos;
     814             : 
     815             : #if defined WNT
     816             :     // Get Javas from the registry
     817             :     addJavaInfoFromWinReg(allInfos, addedInfos);
     818             : #endif // WNT
     819             : 
     820           0 :     if (checkJavaHomeAndPath) {
     821           0 :         addJavaInfoFromJavaHome(allInfos, addedInfos);
     822             :         //this function should be called after addJavaInfosDirScan.
     823             :         //Otherwise in SDKs Java may be started twice
     824           0 :         addJavaInfosFromPath(allInfos, addedInfos);
     825             :     }
     826             : 
     827             : #ifdef UNX
     828           0 :     addJavaInfosDirScan(allInfos, addedInfos);
     829             : #endif
     830             : 
     831           0 :     bubbleSortVersion(addedInfos);
     832           0 :     return addedInfos;
     833             : }
     834             : 
     835             : 
     836         231 : vector<OUString> getVectorFromCharArray(char const * const * ar, int size)
     837             : {
     838         231 :     vector<OUString> vec;
     839        1078 :     for( int i = 0; i < size; i++)
     840             :     {
     841         847 :         OUString s(ar[i], strlen(ar[i]), RTL_TEXTENCODING_UTF8);
     842         847 :         vec.push_back(s);
     843         847 :     }
     844         231 :     return vec;
     845             : }
     846             : 
     847             : /** Checks if the path is a directory. Links are resolved.
     848             :     In case of an error the returned string has the length 0.
     849             :     Otherwise the returned string is the "resolved" file URL.
     850             :  */
     851         150 : OUString resolveDirPath(const OUString & path)
     852             : {
     853         150 :     OUString ret;
     854             :     salhelper::LinkResolver aResolver(osl_FileStatus_Mask_Type |
     855         300 :                                        osl_FileStatus_Mask_FileURL);
     856         150 :     if (aResolver.fetchFileStatus(path) == osl::FileBase::E_None)
     857             :     {
     858             :         //check if this is a directory
     859         150 :         if (aResolver.m_aStatus.getFileType() == FileStatus::Directory)
     860             :         {
     861             : #ifndef JVM_ONE_PATH_CHECK
     862         150 :             ret = aResolver.m_aStatus.getFileURL();
     863             : #else
     864             :             ret = path;
     865             : #endif
     866             :         }
     867             :     }
     868         300 :     return ret;
     869             : }
     870             : /** Checks if the path is a file. If it is a link to a file than
     871             :     it is resolved.
     872             :  */
     873         154 : OUString resolveFilePath(const OUString & path)
     874             : {
     875         154 :     OUString ret;
     876             :     salhelper::LinkResolver aResolver(osl_FileStatus_Mask_Type |
     877         308 :                                        osl_FileStatus_Mask_FileURL);
     878         154 :     if (aResolver.fetchFileStatus(path) == osl::FileBase::E_None)
     879             :     {
     880             :         //check if this is a file
     881          77 :         if (aResolver.m_aStatus.getFileType() == FileStatus::Regular)
     882             :         {
     883             : #ifndef JVM_ONE_PATH_CHECK
     884          77 :             ret = aResolver.m_aStatus.getFileURL();
     885             : #else
     886             :             ret = path;
     887             : #endif
     888             :         }
     889             :     }
     890         308 :     return ret;
     891             : }
     892             : 
     893         150 : rtl::Reference<VendorBase> getJREInfoByPath(
     894             :     const OUString& path)
     895             : {
     896         150 :     rtl::Reference<VendorBase> ret;
     897         150 :     static vector<OUString> vecBadPaths;
     898             : 
     899         150 :     static map<OUString, rtl::Reference<VendorBase> > mapJREs;
     900             :     typedef map<OUString, rtl::Reference<VendorBase> >::const_iterator MapIt;
     901             :     typedef map<OUString, rtl::Reference<VendorBase> > MAPJRE;
     902         300 :     OUString sFilePath;
     903             :     typedef vector<OUString>::const_iterator cit_path;
     904         300 :     vector<pair<OUString, OUString> > props;
     905             : 
     906         300 :     OUString sResolvedDir = resolveDirPath(path);
     907             :     // If this path is invalid then there is no chance to find a JRE here
     908         150 :     if (sResolvedDir.isEmpty())
     909             :     {
     910           0 :         return 0;
     911             :     }
     912             : 
     913             :     //check if the directory path is good, that is a JRE was already recognized.
     914             :     //Then we need not detect it again
     915             :     //For example, a sun JKD contains <jdk>/bin/java and <jdk>/jre/bin/java.
     916             :     //When <jdk>/bin/java has been found then we need not find <jdk>/jre/bin/java.
     917             :     //Otherwise we would execute java two times for evers JDK found.
     918             :     MapIt entry2 = find_if(mapJREs.begin(), mapJREs.end(),
     919         150 :                            SameOrSubDirJREMap(sResolvedDir));
     920         150 :     if (entry2 != mapJREs.end())
     921             :     {
     922             :         JFW_TRACE2("JRE found again (detected before): " << sResolvedDir);
     923          73 :         return entry2->second;
     924             :     }
     925             : 
     926         154 :     for ( sal_Int32 pos = 0;
     927          77 :           gVendorMap[pos].sVendorName != NULL; ++pos )
     928             :     {
     929          77 :         vector<OUString> vecPaths;
     930          77 :         getJavaExePaths_func pFunc = gVendorMap[pos].getJavaFunc;
     931             : 
     932          77 :         int size = 0;
     933          77 :         char const* const* arExePaths = (*pFunc)(&size);
     934          77 :         vecPaths = getVectorFromCharArray(arExePaths, size);
     935             : 
     936          77 :         bool bBreak = false;
     937             :         typedef vector<OUString>::const_iterator c_it;
     938         154 :         for (c_it i = vecPaths.begin(); i != vecPaths.end(); ++i)
     939             :         {
     940             :             //if the path is a link, then resolve it
     941             :             //check if the executable exists at all
     942             : 
     943             :             //path can be only "file:///". Then do not append a '/'
     944             :             //sizeof counts the terminating 0
     945         154 :             OUString sFullPath;
     946         154 :             if (path.getLength() == sizeof("file:///") - 1)
     947           0 :                 sFullPath = sResolvedDir + (*i);
     948             :             else
     949         154 :                 sFullPath = sResolvedDir + "/" + (*i);
     950             : 
     951         154 :             sFilePath = resolveFilePath(sFullPath);
     952             : 
     953         154 :             if (sFilePath.isEmpty())
     954             :             {
     955             :                 //The file path (to java exe) is not valid
     956          77 :                 cit_path ifull = find(vecBadPaths.begin(), vecBadPaths.end(), sFullPath);
     957          77 :                 if (ifull == vecBadPaths.end())
     958             :                 {
     959          77 :                     vecBadPaths.push_back(sFullPath);
     960             :                 }
     961          77 :                 continue;
     962             :             }
     963             : 
     964          77 :             cit_path ifile = find(vecBadPaths.begin(), vecBadPaths.end(), sFilePath);
     965          77 :             if (ifile != vecBadPaths.end())
     966             :             {
     967           0 :                 continue;
     968             :             }
     969             : 
     970          77 :             MapIt entry =  mapJREs.find(sFilePath);
     971          77 :             if (entry != mapJREs.end())
     972             :             {
     973             :                 JFW_TRACE2("JRE found again (detected before): " << sFilePath);
     974             : 
     975           0 :                 return entry->second;
     976             :             }
     977             : 
     978          77 :             bool bProcessRun= false;
     979          77 :             if (!getJavaProps(sFilePath,
     980             : #ifdef JVM_ONE_PATH_CHECK
     981             :                              sResolvedDir,
     982             : #endif
     983          77 :                              props, & bProcessRun))
     984             :             {
     985             :                 //The java executable could not be run or the system properties
     986             :                 //could not be retrieved. We can assume that this java is corrupt.
     987           0 :                 vecBadPaths.push_back(sFilePath);
     988             :                 //If there was a java executable, that could be run but we did not get
     989             :                 //the system properties, then we also assume that the whole Java installation
     990             :                 //does not work. In a jdk there are two executables. One in jdk/bin and the other
     991             :                 //in jdk/jre/bin. We do not search any further, because we assume that if one java
     992             :                 //does not work then the other does not work as well. This saves us to run java
     993             :                 //again which is quite costly.
     994           0 :                 if (bProcessRun)
     995             :                 {
     996             :                     // 1.3.1 special treatment: jdk/bin/java and /jdk/jre/bin/java are links to
     997             :                     //a script, named .java_wrapper. The script starts jdk/bin/sparc/native_threads/java
     998             :                     //or jdk/jre/bin/sparc/native_threads/java. The script uses the name with which it was
     999             :                     //invoked to build the path to the executable. It we start the script directy as .java_wrapper
    1000             :                     //then it tries to start a jdk/.../native_threads/.java_wrapper. Therefore the link, which
    1001             :                     //is named java, must be used to start the script.
    1002             :                     getJavaProps(sFullPath,
    1003             : #ifdef JVM_ONE_PATH_CHECK
    1004             :                                  sResolvedDir,
    1005             : #endif
    1006           0 :                                  props, & bProcessRun);
    1007             :                     // Either we found a working 1.3.1
    1008             :                     //Or the java is broken. In both cases we stop searchin under this "root" directory
    1009           0 :                     bBreak = true;
    1010           0 :                     break;
    1011             :                 }
    1012             :                 //sFilePath is no working java executable. We continue with another possible
    1013             :                 //path.
    1014             :                 else
    1015             :                 {
    1016           0 :                     continue;
    1017             :                 }
    1018             :             }
    1019             :             //sFilePath is a java and we could get the system properties. We proceed with this
    1020             :             //java.
    1021             :             else
    1022             :             {
    1023          77 :                 bBreak = true;
    1024          77 :                 break;
    1025             :             }
    1026           0 :         }
    1027          77 :         if (bBreak)
    1028          77 :             break;
    1029           0 :     }
    1030             : 
    1031          77 :     if (props.empty())
    1032             :     {
    1033           0 :         return rtl::Reference<VendorBase>();
    1034             :     }
    1035             : 
    1036             :     //find java.vendor property
    1037             :     typedef vector<pair<OUString, OUString> >::const_iterator c_ip;
    1038         154 :     OUString sVendor("java.vendor");
    1039         154 :     OUString sVendorName;
    1040             : 
    1041        3542 :     for (c_ip i = props.begin(); i != props.end(); ++i)
    1042             :     {
    1043        3542 :         if (sVendor.equals(i->first))
    1044             :         {
    1045          77 :             sVendorName = i->second;
    1046          77 :             break;
    1047             :         }
    1048             :     }
    1049             : 
    1050          77 :     if (!sVendorName.isEmpty())
    1051             :     {
    1052             :         //find the creator func for the respective vendor name
    1053         308 :         for ( sal_Int32 c = 0;
    1054         154 :               gVendorMap[c].sVendorName != NULL; ++c )
    1055             :         {
    1056         154 :             OUString sNameMap(gVendorMap[c].sVendorName, strlen(gVendorMap[c].sVendorName),
    1057         154 :                               RTL_TEXTENCODING_ASCII_US);
    1058         154 :             if (sNameMap.equals(sVendorName))
    1059             :             {
    1060          77 :                 ret = createInstance(gVendorMap[c].createFunc, props);
    1061          77 :                 break;
    1062             :             }
    1063          77 :         }
    1064             :     }
    1065          77 :     if (!ret.is())
    1066             :     {
    1067           0 :         vecBadPaths.push_back(sFilePath);
    1068             :     }
    1069             :     else
    1070             :     {
    1071             :         JFW_TRACE2("Found JRE: " << sResolvedDir << " at: " << path);
    1072             : 
    1073          77 :         mapJREs.insert(MAPJRE::value_type(sResolvedDir, ret));
    1074          77 :         mapJREs.insert(MAPJRE::value_type(sFilePath, ret));
    1075             :     }
    1076             : 
    1077         227 :     return ret;
    1078             : }
    1079             : 
    1080          77 : Reference<VendorBase> createInstance(createInstance_func pFunc,
    1081             :                                      vector<pair<OUString, OUString> > properties)
    1082             : {
    1083             : 
    1084          77 :     Reference<VendorBase> aBase = (*pFunc)();
    1085          77 :     if (aBase.is())
    1086             :     {
    1087          77 :         if (!aBase->initialize(properties))
    1088           0 :             aBase = 0;
    1089             :     }
    1090          77 :     return aBase;
    1091             : }
    1092             : 
    1093         154 : inline OUString getDirFromFile(const OUString& usFilePath)
    1094             : {
    1095         154 :     sal_Int32 index = usFilePath.lastIndexOf('/');
    1096         154 :     return usFilePath.copy(0, index);
    1097             : }
    1098             : 
    1099           0 : void addJavaInfosFromPath(
    1100             :     std::vector<rtl::Reference<VendorBase>> & allInfos,
    1101             :     std::vector<rtl::Reference<VendorBase>> & addedInfos)
    1102             : {
    1103             : #if !defined JVM_ONE_PATH_CHECK
    1104             : // Get Java from PATH environment variable
    1105           0 :     char *szPath= getenv("PATH");
    1106           0 :     if(szPath)
    1107             :     {
    1108           0 :         OUString usAllPath(szPath, strlen(szPath), osl_getThreadTextEncoding());
    1109           0 :         sal_Int32 nIndex = 0;
    1110           0 :         do
    1111             :         {
    1112           0 :             OUString usToken = usAllPath.getToken( 0, SAL_PATHSEPARATOR, nIndex );
    1113           0 :             OUString usTokenUrl;
    1114           0 :             if(File::getFileURLFromSystemPath(usToken, usTokenUrl) == File::E_None)
    1115             :             {
    1116           0 :                 if(!usTokenUrl.isEmpty())
    1117             :                 {
    1118           0 :                     OUString usBin;
    1119           0 :                     if(usTokenUrl == ".")
    1120             :                     {
    1121           0 :                         OUString usWorkDirUrl;
    1122           0 :                         if(osl_Process_E_None == osl_getProcessWorkingDir(&usWorkDirUrl.pData))
    1123           0 :                             usBin= usWorkDirUrl;
    1124             :                     }
    1125           0 :                     else if(usTokenUrl == "..")
    1126             :                     {
    1127           0 :                         OUString usWorkDir;
    1128           0 :                         if(osl_Process_E_None == osl_getProcessWorkingDir(&usWorkDir.pData))
    1129           0 :                             usBin= getDirFromFile(usWorkDir);
    1130             :                     }
    1131             :                     else
    1132             :                     {
    1133           0 :                         usBin = usTokenUrl;
    1134             :                     }
    1135           0 :                     if(!usBin.isEmpty())
    1136             :                     {
    1137           0 :                         addJREInfoFromBinPath(usBin, allInfos, addedInfos);
    1138           0 :                     }
    1139             :                 }
    1140           0 :             }
    1141             :         }
    1142           0 :         while ( nIndex >= 0 );
    1143             :     }
    1144             : #endif
    1145           0 : }
    1146             : 
    1147             : 
    1148           4 : void addJavaInfoFromJavaHome(
    1149             :     std::vector<rtl::Reference<VendorBase>> & allInfos,
    1150             :     std::vector<rtl::Reference<VendorBase>> & addedInfos)
    1151             : {
    1152             : #if !defined JVM_ONE_PATH_CHECK
    1153             :     // Get Java from JAVA_HOME environment
    1154             : 
    1155             :     // Note that on OS X is it not normal at all to have a JAVA_HOME environment
    1156             :     // variable. We set it in our build environment for build-time programs, though,
    1157             :     // so it is set when running unit tests that involve Java functionality. (Which affects
    1158             :     // at least CppunitTest_dbaccess_dialog_save, too, and not only the JunitTest ones.)
    1159           4 :     char *szJavaHome= getenv("JAVA_HOME");
    1160           4 :     if(szJavaHome)
    1161             :     {
    1162           4 :         OUString sHome(szJavaHome, strlen(szJavaHome), osl_getThreadTextEncoding());
    1163           8 :         OUString sHomeUrl;
    1164           4 :         if(File::getFileURLFromSystemPath(sHome, sHomeUrl) == File::E_None)
    1165             :         {
    1166           4 :             getAndAddJREInfoByPath(sHomeUrl, allInfos, addedInfos);
    1167           4 :         }
    1168             :     }
    1169             : #endif
    1170           4 : }
    1171             : 
    1172          77 : bool makeDriveLetterSame(OUString * fileURL)
    1173             : {
    1174          77 :     bool ret = false;
    1175          77 :     DirectoryItem item;
    1176          77 :     if (DirectoryItem::get(*fileURL, item) == File::E_None)
    1177             :     {
    1178          77 :         FileStatus status(osl_FileStatus_Mask_FileURL);
    1179          77 :         if (item.getFileStatus(status) == File::E_None)
    1180             :         {
    1181          77 :             *fileURL = status.getFileURL();
    1182          77 :             ret = true;
    1183          77 :         }
    1184             :     }
    1185          77 :     return ret;
    1186             : }
    1187             : 
    1188             : #ifdef UNX
    1189             : #ifdef SOLARIS
    1190             : 
    1191             : void addJavaInfosDirScan(
    1192             :     std::vector<rtl::Reference<VendorBase>> & allInfos,
    1193             :     std::vector<rtl::Reference<VendorBase>> & addedInfos)
    1194             : {
    1195             :     JFW_TRACE2("Checking /usr/jdk/latest");
    1196             :     getAndAddJREInfoByPath("file:////usr/jdk/latest", allInfos, addedInfos);
    1197             : }
    1198             : 
    1199             : #elif defined MACOSX && defined X86_64
    1200             : 
    1201             : void addJavaInfosDirScan(
    1202             :     std::vector<rtl::Reference<VendorBase>> & allInfos,
    1203             :     std::vector<rtl::Reference<VendorBase>> & addedInfos)
    1204             : {
    1205             :     // Oracle Java 7
    1206             :     getAndAddJREInfoByPath("file:///Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home", allInfos, addedInfos);
    1207             : }
    1208             : 
    1209             : #else
    1210           0 : void addJavaInfosDirScan(
    1211             :     std::vector<rtl::Reference<VendorBase>> & allInfos,
    1212             :     std::vector<rtl::Reference<VendorBase>> & addedInfos)
    1213             : {
    1214             :     OUString excMessage = "[Java framework] sunjavaplugin: "
    1215           0 :                           "Error in function addJavaInfosDirScan in util.cxx.";
    1216           0 :     int cJavaNames= sizeof(g_arJavaNames) / sizeof(char*);
    1217           0 :     boost::scoped_array<OUString> sarJavaNames(new OUString[cJavaNames]);
    1218           0 :     OUString *arNames = sarJavaNames.get();
    1219           0 :     for(int i= 0; i < cJavaNames; i++)
    1220           0 :         arNames[i] = OUString(g_arJavaNames[i], strlen(g_arJavaNames[i]),
    1221           0 :                               RTL_TEXTENCODING_UTF8);
    1222             : 
    1223           0 :     int cSearchPaths= sizeof(g_arSearchPaths) / sizeof(char*);
    1224           0 :     boost::scoped_array<OUString> sarPathNames(new OUString[cSearchPaths]);
    1225           0 :     OUString *arPaths = sarPathNames.get();
    1226           0 :     for(int c = 0; c < cSearchPaths; c++)
    1227           0 :         arPaths[c] = OUString(g_arSearchPaths[c], strlen(g_arSearchPaths[c]),
    1228           0 :                                RTL_TEXTENCODING_UTF8);
    1229             : 
    1230           0 :     int cCollectDirs = sizeof(g_arCollectDirs) / sizeof(char*);
    1231           0 :     boost::scoped_array<OUString> sarCollectDirs(new OUString[cCollectDirs]);
    1232           0 :     OUString *arCollectDirs = sarCollectDirs.get();
    1233           0 :     for(int d = 0; d < cCollectDirs; d++)
    1234           0 :         arCollectDirs[d] = OUString(g_arCollectDirs[d], strlen(g_arCollectDirs[d]),
    1235           0 :                                RTL_TEXTENCODING_UTF8);
    1236             : 
    1237             : 
    1238             : 
    1239           0 :     OUString usFile("file:///");
    1240           0 :     for( int ii = 0; ii < cSearchPaths; ii ++)
    1241             :     {
    1242           0 :         OUString usDir1(usFile + arPaths[ii]);
    1243           0 :         DirectoryItem item;
    1244           0 :         if(DirectoryItem::get(usDir1, item) == File::E_None)
    1245             :         {
    1246           0 :             for(int j= 0; j < cCollectDirs; j++)
    1247             :             {
    1248           0 :                 OUString usDir2(usDir1 + arCollectDirs[j]);
    1249             :                 // prevent that we scan the whole /usr, /usr/lib, etc directories
    1250           0 :                 if (!arCollectDirs[j].isEmpty())
    1251             :                 {
    1252             :                     //usr/java/xxx
    1253             :                     //Examin every subdirectory
    1254           0 :                     Directory aCollectionDir(usDir2);
    1255             : 
    1256           0 :                     Directory::RC openErr = aCollectionDir.open();
    1257           0 :                     switch (openErr)
    1258             :                     {
    1259             :                     case File::E_None:
    1260           0 :                         break;
    1261             :                     case File::E_NOENT:
    1262             :                     case File::E_NOTDIR:
    1263           0 :                         continue;
    1264             :                     case File::E_ACCES:
    1265             :                         JFW_TRACE2("Could not read directory " << usDir2 << " because of missing access rights");
    1266           0 :                         continue;
    1267             :                     default:
    1268             :                         JFW_TRACE2("Could not read directory " << usDir2 << ". Osl file error: " << openErr);
    1269           0 :                         continue;
    1270             :                     }
    1271             : 
    1272           0 :                     DirectoryItem curIt;
    1273           0 :                     File::RC errNext = File::E_None;
    1274           0 :                     while( (errNext = aCollectionDir.getNextItem(curIt)) == File::E_None)
    1275             :                     {
    1276           0 :                         FileStatus aStatus(osl_FileStatus_Mask_FileURL);
    1277           0 :                         File::RC errStatus = File::E_None;
    1278           0 :                         if ((errStatus = curIt.getFileStatus(aStatus)) != File::E_None)
    1279             :                         {
    1280             :                             JFW_TRACE2(excMessage + "getFileStatus failed with error " << errStatus);
    1281           0 :                             continue;
    1282             :                         }
    1283             :                         JFW_TRACE2("Checking if directory: " << aStatus.getFileURL() << " is a Java");
    1284             : 
    1285             :                         getAndAddJREInfoByPath(
    1286           0 :                             aStatus.getFileURL(), allInfos, addedInfos);
    1287           0 :                     }
    1288             : 
    1289             :                     JFW_ENSURE(errNext == File::E_None || errNext == File::E_NOENT,
    1290             :                                 "[Java framework] sunjavaplugin: "
    1291             :                                 "Error while iterating over contens of "
    1292             :                                 + usDir2 + ". Osl file error: "
    1293           0 :                                 + OUString::number(openErr));
    1294             :                 }
    1295             :                 else
    1296             :                 {
    1297             :                     //usr/java
    1298             :                     //When we look directly into a dir like /usr, /usr/lib, etc. then we only
    1299             :                     //look for certain java directories, such as jre, jdk, etc. Whe do not want
    1300             :                     //to examine the whole directory because of performance reasons.
    1301           0 :                     DirectoryItem item2;
    1302           0 :                     if(DirectoryItem::get(usDir2, item2) == File::E_None)
    1303             :                     {
    1304           0 :                         for( int k= 0; k < cJavaNames; k++)
    1305             :                         {
    1306             :                             // /usr/java/j2re1.4.0
    1307           0 :                             OUString usDir3(usDir2 + arNames[k]);
    1308             : 
    1309           0 :                             DirectoryItem item3;
    1310           0 :                             if(DirectoryItem::get(usDir3, item) == File::E_None)
    1311             :                             {
    1312             :                                 //remove trailing '/'
    1313           0 :                                 sal_Int32 islash = usDir3.lastIndexOf('/');
    1314           0 :                                 if (islash == usDir3.getLength() - 1
    1315           0 :                                     && (islash
    1316           0 :                                         > RTL_CONSTASCII_LENGTH("file://")))
    1317           0 :                                     usDir3 = usDir3.copy(0, islash);
    1318             :                                 getAndAddJREInfoByPath(
    1319           0 :                                     usDir3, allInfos, addedInfos);
    1320             :                             }
    1321           0 :                         }
    1322           0 :                     }
    1323             :                 }
    1324           0 :             }
    1325             :         }
    1326           0 :     }
    1327           0 : }
    1328             : #endif // ifdef SOLARIS
    1329             : #endif // ifdef UNX
    1330             : }
    1331             : 
    1332             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11