LCOV - code coverage report
Current view: top level - jvmfwk/plugins/sunmajor/pluginlib - util.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 218 420 51.9 %
Date: 2012-08-25 Functions: 23 31 74.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 172 597 28.8 %

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

Generated by: LCOV version 1.10