LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/jvmfwk/plugins/sunmajor/pluginlib - util.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 375 434 86.4 %
Date: 2013-07-09 Functions: 30 31 96.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10