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