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