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: */
|