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