xref: /trunk/main/jvmfwk/source/framework.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_jvmfwk.hxx"
30 #include "boost/scoped_array.hpp"
31 #include "rtl/ustring.hxx"
32 #include "rtl/bootstrap.hxx"
33 #include "osl/thread.hxx"
34 #include "osl/file.hxx"
35 #include "osl/module.hxx"
36 #include "jvmfwk/framework.h"
37 #include "jvmfwk/vendorplugin.h"
38 #include <vector>
39 #include <functional>
40 #include <algorithm>
41 #include "framework.hxx"
42 #include "fwkutil.hxx"
43 #include "elements.hxx"
44 #include "fwkbase.hxx"
45 
46 #ifdef WNT
47 /** The existence of the file useatjava.txt decides if a Java should be used
48     that supports accessibility tools.
49  */
50 #define USE_ACCESSIBILITY_FILE "useatjava.txt"
51 #endif
52 
53 #define UNO_JAVA_JFW_JREHOME "UNO_JAVA_JFW_JREHOME"
54 namespace {
55 JavaVM * g_pJavaVM = NULL;
56 
57 bool g_bEnabledSwitchedOn = false;
58 
59 sal_Bool areEqualJavaInfo(
60     JavaInfo const * pInfoA,JavaInfo const * pInfoB)
61 {
62     return jfw_areEqualJavaInfo(pInfoA, pInfoB);
63 }
64 }
65 
66 javaFrameworkError SAL_CALL jfw_findAllJREs(JavaInfo ***pparInfo, sal_Int32 *pSize)
67 {
68     javaFrameworkError retVal = JFW_E_NONE;
69     try
70     {
71         osl::MutexGuard guard(jfw::FwkMutex::get());
72         javaFrameworkError errcode = JFW_E_NONE;
73         if (pparInfo == NULL || pSize == NULL)
74             return JFW_E_INVALID_ARG;
75 
76         jfw::VendorSettings aVendorSettings;
77         //Get a list of plugins which provide Java information
78         std::vector<jfw::PluginLibrary> vecPlugins =
79             aVendorSettings.getPluginData();
80 
81         //Create a vector that holds the libraries, which will be later
82         //dynamically loaded;
83         boost::scoped_array<osl::Module> sarModules;
84         sarModules.reset(new osl::Module[vecPlugins.size()]);
85         osl::Module * arModules = sarModules.get();
86         //Add the JavaInfos found by jfw_plugin_getAllJavaInfos to the vector
87         //Make sure that the contents are destroyed if this
88         //function returns with an error
89         std::vector<jfw::CJavaInfo> vecInfo;
90         //Add the JavaInfos found by jfw_plugin_getJavaInfoByPath to this vector
91         //Make sure that the contents are destroyed if this
92         //function returns with an error
93         std::vector<jfw::CJavaInfo> vecInfoManual;
94         typedef std::vector<jfw::CJavaInfo>::iterator it_info;
95         //get the list of paths to jre locations which have been
96         //added manually
97         const jfw::MergedSettings settings;
98         const std::vector<rtl::OUString>& vecJRELocations =
99             settings.getJRELocations();
100         //Use every plug-in library to get Java installations.
101         typedef std::vector<jfw::PluginLibrary>::const_iterator ci_pl;
102         int cModule = 0;
103         for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); i++, cModule++)
104         {
105             const jfw::PluginLibrary & library = *i;
106             jfw::VersionInfo versionInfo =
107                 aVendorSettings.getVersionInformation(library.sVendor);
108             arModules[cModule].load(library.sPath);
109             osl::Module & pluginLib = arModules[cModule];
110 
111             if (pluginLib.is() == sal_False)
112             {
113                 rtl::OString msg = rtl::OUStringToOString(
114                     library.sPath, osl_getThreadTextEncoding());
115                 fprintf(stderr,"[jvmfwk] Could not load plugin %s\n" \
116                         "Modify the javavendors.xml accordingly!\n", msg.getStr());
117                 return JFW_E_NO_PLUGIN;
118             }
119             jfw_plugin_getAllJavaInfos_ptr getAllJavaFunc =
120                 (jfw_plugin_getAllJavaInfos_ptr) pluginLib.getFunctionSymbol(
121                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getAllJavaInfos")));
122 
123             OSL_ASSERT(getAllJavaFunc);
124             if (getAllJavaFunc == NULL)
125                 return JFW_E_ERROR;
126 
127             //get all installations of one vendor according to minVersion,
128             //maxVersion and excludeVersions
129             sal_Int32 cInfos = 0;
130             JavaInfo** arInfos = NULL;
131             javaPluginError plerr  = (*getAllJavaFunc)(
132                 library.sVendor.pData,
133                 versionInfo.sMinVersion.pData,
134                 versionInfo.sMaxVersion.pData,
135                 versionInfo.getExcludeVersions(),
136                 versionInfo.getExcludeVersionSize(),
137                 & arInfos,
138                 & cInfos);
139 
140             if (plerr != JFW_PLUGIN_E_NONE)
141                 return JFW_E_ERROR;
142 
143             for (int j = 0; j < cInfos; j++)
144                 vecInfo.push_back(jfw::CJavaInfo::createWrapper(arInfos[j]));
145 
146             rtl_freeMemory(arInfos);
147 
148             //Check if the current plugin can detect JREs at the location
149             // of the paths added by jfw_setJRELocations or jfw_addJRELocation
150             //get the function from the plugin
151             jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc =
152                 (jfw_plugin_getJavaInfoByPath_ptr) pluginLib.getFunctionSymbol(
153                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getJavaInfoByPath")));
154 
155             OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc);
156             if (jfw_plugin_getJavaInfoByPathFunc == NULL)
157                 return JFW_E_ERROR;
158 
159             typedef std::vector<rtl::OUString>::const_iterator citLoc;
160             //Check every manually added location
161             for (citLoc ii = vecJRELocations.begin();
162                 ii != vecJRELocations.end(); ii++)
163             {
164 //              rtl::OUString sLocation =
165 //                  rtl::OStringToOUString(*ii, RTL_TEXTENCODING_UTF8);
166                 jfw::CJavaInfo aInfo;
167                 plerr = (*jfw_plugin_getJavaInfoByPathFunc)(
168                     ii->pData,
169                     library.sVendor.pData,
170                     versionInfo.sMinVersion.pData,
171                     versionInfo.sMaxVersion.pData,
172                     versionInfo.getExcludeVersions(),
173                     versionInfo.getExcludeVersionSize(),
174                     & aInfo.pInfo);
175                 if (plerr == JFW_PLUGIN_E_NO_JRE)
176                     continue;
177                 if (plerr == JFW_PLUGIN_E_FAILED_VERSION)
178                     continue;
179                 else if (plerr !=JFW_PLUGIN_E_NONE)
180                     return JFW_E_ERROR;
181 
182                 if (aInfo)
183                 {
184                     //Was this JRE already added?. Different plugins could detect
185                     //the same JRE
186                     it_info it_duplicate =
187                         std::find_if(vecInfoManual.begin(), vecInfoManual.end(),
188                                 std::bind2nd(std::ptr_fun(areEqualJavaInfo), aInfo));
189                     if (it_duplicate == vecInfoManual.end())
190                         vecInfoManual.push_back(aInfo);
191                 }
192             }
193         }
194         //Make sure vecInfoManual contains only JavaInfos for the vendors for which
195         //there is a javaSelection/plugins/library entry in the javavendors.xml
196         //To obtain the JavaInfos for the manually added JRE locations the function
197         //jfw_getJavaInfoByPath is called which can return a JavaInfo of any vendor.
198         std::vector<jfw::CJavaInfo> vecInfoManual2;
199         for (it_info ivm = vecInfoManual.begin(); ivm != vecInfoManual.end(); ivm++)
200         {
201             for (ci_pl ii = vecPlugins.begin(); ii != vecPlugins.end(); ii++)
202             {
203                 if ( ii->sVendor.equals((*ivm)->sVendor))
204                 {
205                     vecInfoManual2.push_back(*ivm);
206                     break;
207                 }
208             }
209         }
210         //Check which JavaInfo from vector vecInfoManual2 is already
211         //contained in vecInfo. If it already exists then remove it from
212         //vecInfoManual2
213         for (it_info j = vecInfo.begin(); j != vecInfo.end(); j++)
214         {
215             it_info it_duplicate =
216                 std::find_if(vecInfoManual2.begin(), vecInfoManual2.end(),
217                             std::bind2nd(std::ptr_fun(areEqualJavaInfo), *j));
218             if (it_duplicate != vecInfoManual2.end())
219                 vecInfoManual2.erase(it_duplicate);
220         }
221         //create an fill the array of JavaInfo*
222         sal_Int32 nSize = vecInfo.size() + vecInfoManual2.size();
223         *pparInfo = (JavaInfo**) rtl_allocateMemory(
224             nSize * sizeof(JavaInfo*));
225         if (*pparInfo == NULL)
226             return JFW_E_ERROR;
227 
228         typedef std::vector<jfw::CJavaInfo>::iterator it;
229         int index = 0;
230         //Add the automatically detected JREs
231         for (it k = vecInfo.begin(); k != vecInfo.end(); k++)
232             (*pparInfo)[index++] = k->detach();
233         //Add the manually detected JREs
234         for (it l = vecInfoManual2.begin(); l != vecInfoManual2.end(); l++)
235             (*pparInfo)[index++] = l->detach();
236 
237         *pSize = nSize;
238         return errcode;
239     }
240     catch (jfw::FrameworkException& e)
241     {
242         retVal = e.errorCode;
243         fprintf(stderr, "%s\n", e.message.getStr());
244         OSL_ENSURE(0, e.message.getStr());
245     }
246     return retVal;
247 }
248 
249 javaFrameworkError SAL_CALL jfw_startVM(JavaVMOption *arOptions, sal_Int32 cOptions,
250                                  JavaVM **ppVM, JNIEnv **ppEnv)
251 {
252 #ifndef SOLAR_JAVA
253     return JFW_E_ERROR;
254 #else
255     javaFrameworkError errcode = JFW_E_NONE;
256     if (cOptions > 0 && arOptions == NULL)
257         return JFW_E_INVALID_ARG;
258 
259     try
260     {
261         osl::MutexGuard guard(jfw::FwkMutex::get());
262 
263         //We keep this pointer so we can determine if a VM has already
264         //been created.
265         if (g_pJavaVM != NULL)
266             return JFW_E_RUNNING_JVM;
267 
268         if (ppVM == NULL)
269             return JFW_E_INVALID_ARG;
270 
271         std::vector<rtl::OString> vmParams;
272         rtl::OString sUserClassPath;
273         jfw::CJavaInfo aInfo;
274         jfw::JFW_MODE mode = jfw::getMode();
275         if (mode == jfw::JFW_MODE_APPLICATION)
276         {
277             const jfw::MergedSettings settings;
278             if (sal_False == settings.getEnabled())
279                 return JFW_E_JAVA_DISABLED;
280             aInfo.attach(settings.createJavaInfo());
281             //check if a Java has ever been selected
282             if (aInfo == NULL)
283                 return JFW_E_NO_SELECT;
284 
285 #ifdef WNT
286             //Because on Windows there is no system setting that we can use to determine
287             //if Assistive Technology Tool support is needed, we ship a .reg file that the
288             //user can use to create a registry setting. When the user forgets to set
289             //the key before he starts the office then a JRE may be selected without access bridge.
290             //When he later sets the key then we select a JRE with accessibility support but
291             //only if the user has not manually changed the selected JRE in the options dialog.
292             if (jfw::isAccessibilitySupportDesired())
293             {
294                 // If no JRE has been selected then we do not select one. This function shall then
295                 //return JFW_E_NO_SELECT
296                 if (aInfo != NULL &&
297                     (aInfo->nFeatures & JFW_FEATURE_ACCESSBRIDGE) == 0)
298                 {
299                     //has the user manually selected a JRE?
300                     if (settings.getJavaInfoAttrAutoSelect() == true)
301                     {
302                         // if not then the automatism has previously selected a JRE
303                         //without accessibility support. We return JFW_E_NO_SELECT
304                         //to cause that we search for another JRE. The search code will
305                         //then prefer a JRE with accessibility support.
306                         return JFW_E_NO_SELECT;
307                     }
308                 }
309             }
310 #endif
311             //check if the javavendors.xml has changed after a Java was selected
312             rtl::OString sVendorUpdate = jfw::getElementUpdated();
313 
314             if (sVendorUpdate != settings.getJavaInfoAttrVendorUpdate())
315                 return JFW_E_INVALID_SETTINGS;
316 
317             //check if JAVA is disabled
318             //If Java is enabled, but it was disabled when this process was started
319             // then no preparational work, such as setting the LD_LIBRARY_PATH, was
320             //done. Therefore if a JRE needs it it must not be started.
321             if (g_bEnabledSwitchedOn &&
322                     (aInfo->nRequirements & JFW_REQUIRE_NEEDRESTART))
323                 return JFW_E_NEED_RESTART;
324 
325             //Check if the selected Java was set in this process. If so it
326             //must not have the requirments flag JFW_REQUIRE_NEEDRESTART
327             if ((aInfo->nRequirements & JFW_REQUIRE_NEEDRESTART)
328                 &&
329                 (jfw::wasJavaSelectedInSameProcess() == true))
330                 return JFW_E_NEED_RESTART;
331 
332             vmParams = settings.getVmParametersUtf8();
333             sUserClassPath = jfw::makeClassPathOption(settings.getUserClassPath());
334         } // end mode FWK_MODE_OFFICE
335         else if (mode == jfw::JFW_MODE_DIRECT)
336         {
337             errcode = jfw_getSelectedJRE(&aInfo.pInfo);
338             if (errcode != JFW_E_NONE)
339                 return errcode;
340             //In direct mode the options are specified by bootstrap variables
341             //of the form UNO_JAVA_JFW_PARAMETER_1 .. UNO_JAVA_JFW_PARAMETER_n
342             vmParams = jfw::BootParams::getVMParameters();
343             sUserClassPath =
344                 "-Djava.class.path=" + jfw::BootParams::getClasspath();
345         }
346         else
347             OSL_ASSERT(0);
348 
349         //get the function jfw_plugin_startJavaVirtualMachine
350         jfw::VendorSettings aVendorSettings;
351         rtl::OUString sLibPath = aVendorSettings.getPluginLibrary(aInfo.getVendor());
352 
353         osl::Module modulePlugin(sLibPath);
354         if ( ! modulePlugin)
355             return JFW_E_NO_PLUGIN;
356 
357         rtl::OUString sFunctionName(
358             RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_startJavaVirtualMachine"));
359         jfw_plugin_startJavaVirtualMachine_ptr pFunc =
360             (jfw_plugin_startJavaVirtualMachine_ptr)
361             osl_getFunctionSymbol(modulePlugin, sFunctionName.pData);
362         if (pFunc == NULL)
363             return JFW_E_ERROR;
364 
365         // create JavaVMOptions array that is passed to the plugin
366         // it contains the classpath and all options set in the
367         //options dialog
368         boost::scoped_array<JavaVMOption> sarJOptions(
369             new JavaVMOption[cOptions + 2 + vmParams.size()]);
370         JavaVMOption * arOpt = sarJOptions.get();
371         if (! arOpt)
372             return JFW_E_ERROR;
373 
374         //The first argument is the classpath
375         arOpt[0].optionString= (char*) sUserClassPath.getStr();
376         arOpt[0].extraInfo = NULL;
377         // Set a flag that this JVM has been created via the JNI Invocation API
378         // (used, for example, by UNO remote bridges to share a common thread pool
379         // factory among Java and native bridge implementations):
380         arOpt[1].optionString = (char *) "-Dorg.openoffice.native=";
381         arOpt[1].extraInfo = 0;
382 
383         //add the options set by options dialog
384         int index = 2;
385         typedef std::vector<rtl::OString>::const_iterator cit;
386         for (cit i = vmParams.begin(); i != vmParams.end(); i ++)
387         {
388             arOpt[index].optionString = const_cast<sal_Char*>(i->getStr());
389             arOpt[index].extraInfo = 0;
390             index ++;
391         }
392         //add all options of the arOptions argument
393         for (int ii = 0; ii < cOptions; ii++)
394         {
395             arOpt[index].optionString = arOptions[ii].optionString;
396             arOpt[index].extraInfo = arOptions[ii].extraInfo;
397             index++;
398         }
399 
400         //start Java
401         JavaVM *pVm = NULL;
402         javaPluginError plerr = (*pFunc)(aInfo, arOpt, index, & pVm, ppEnv);
403         if (plerr == JFW_PLUGIN_E_VM_CREATION_FAILED)
404         {
405             errcode = JFW_E_VM_CREATION_FAILED;
406         }
407         else if (plerr != JFW_PLUGIN_E_NONE )
408         {
409             errcode = JFW_E_ERROR;
410         }
411         else
412         {
413             g_pJavaVM = pVm;
414             *ppVM = pVm;
415         }
416         OSL_ASSERT(plerr != JFW_PLUGIN_E_WRONG_VENDOR);
417     }
418     catch (jfw::FrameworkException& e)
419     {
420         errcode = e.errorCode;
421         fprintf(stderr, "%s\n", e.message.getStr());
422         OSL_ENSURE(0, e.message.getStr());
423     }
424 
425     return errcode;
426 #endif
427 }
428 
429 /** We do not use here jfw_findAllJREs and then check if a JavaInfo
430     meets the requirements, because that means using all plug-ins, which
431     may take quite a while. The implementation uses one plug-in and if
432     it already finds a suitable JRE then it is done and does not need to
433     load another plug-in
434  */
435 javaFrameworkError SAL_CALL jfw_findAndSelectJRE(JavaInfo **pInfo)
436 {
437     javaFrameworkError errcode = JFW_E_NONE;
438     try
439     {
440         osl::MutexGuard guard(jfw::FwkMutex::get());
441         if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
442             return JFW_E_DIRECT_MODE;
443         sal_uInt64 nFeatureFlags = 0;
444         jfw::CJavaInfo aCurrentInfo;
445 //Determine if accessibility support is needed
446         bool bSupportAccessibility = jfw::isAccessibilitySupportDesired();
447         nFeatureFlags = bSupportAccessibility ?
448             JFW_FEATURE_ACCESSBRIDGE : 0L;
449 
450         //Get a list of services which provide Java information
451         jfw::VendorSettings aVendorSettings;
452         std::vector<jfw::PluginLibrary> vecPlugins =
453             aVendorSettings.getPluginData();
454         //Create a vector that holds the libraries, which will be later
455         //dynamically loaded;
456         boost::scoped_array<osl::Module> sarModules;
457         sarModules.reset(new osl::Module[vecPlugins.size()]);
458         osl::Module * arModules = sarModules.get();
459 
460         //Use every plug-in library to get Java installations. At the first usable
461         //Java the loop will break
462         typedef std::vector<jfw::PluginLibrary>::const_iterator ci_pl;
463         int cModule = 0;
464         for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); i++, cModule++)
465         {
466             const jfw::PluginLibrary & library = *i;
467             jfw::VersionInfo versionInfo =
468                 aVendorSettings.getVersionInformation(library.sVendor);
469 
470             arModules[cModule].load(library.sPath);
471             osl::Module & pluginLib = arModules[cModule];
472             if (pluginLib.is() == sal_False)
473                 return JFW_E_NO_PLUGIN;
474 
475             jfw_plugin_getAllJavaInfos_ptr getAllJavaFunc =
476                 (jfw_plugin_getAllJavaInfos_ptr) pluginLib.getFunctionSymbol(
477                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getAllJavaInfos")));
478 
479             OSL_ASSERT(getAllJavaFunc);
480             if (getAllJavaFunc == NULL)
481                 continue;
482 
483             //get all installations of one vendor according to minVersion,
484             //maxVersion and excludeVersions
485             sal_Int32 cInfos = 0;
486             JavaInfo** arInfos = NULL;
487             javaPluginError plerr  = (*getAllJavaFunc)(
488                 library.sVendor.pData,
489                 versionInfo.sMinVersion.pData,
490                 versionInfo.sMaxVersion.pData,
491                 versionInfo.getExcludeVersions(),
492                 versionInfo.getExcludeVersionSize(),
493                 & arInfos,
494                 & cInfos);
495 
496             if (plerr != JFW_PLUGIN_E_NONE)
497                 continue;
498             //iterate over all installations to find the best which has
499             //all features
500             if (cInfos == 0)
501             {
502                 rtl_freeMemory(arInfos);
503                 continue;
504             }
505             bool bInfoFound = false;
506             for (int ii = 0; ii < cInfos; ii++)
507             {
508                 JavaInfo* pJInfo = arInfos[ii];
509 
510                 //We remember the very first installation in aCurrentInfo
511                 if (aCurrentInfo.getLocation().getLength() == 0)
512                         aCurrentInfo = pJInfo;
513                 // compare features
514                 // If the user does not require any features (nFeatureFlags = 0)
515                 // then the first installation is used
516                 if ((pJInfo->nFeatures & nFeatureFlags) == nFeatureFlags)
517                 {
518                     //the just found Java implements all required features
519                     //currently there is only accessibility!!!
520                     aCurrentInfo = pJInfo;
521                     bInfoFound = true;
522                     break;
523                 }
524             }
525             //The array returned by jfw_plugin_getAllJavaInfos must be freed as well as
526             //its contents
527             for (int j = 0; j < cInfos; j++)
528                 jfw_freeJavaInfo(arInfos[j]);
529             rtl_freeMemory(arInfos);
530 
531             if (bInfoFound == true)
532                 break;
533             //All Java installations found by the current plug-in lib
534             //do not provide the required features. Try the next plug-in
535         }
536         if ((JavaInfo*) aCurrentInfo == NULL)
537         {//The plug-ins did not find a suitable Java. Now try the paths which have been
538         //added manually.
539             //get the list of paths to jre locations which have been added manually
540             const jfw::MergedSettings settings;
541             //node.loadFromSettings();
542             const std::vector<rtl::OUString> & vecJRELocations =
543                 settings.getJRELocations();
544             //use every plug-in to determine the JavaInfo objects
545             bool bInfoFound = false;
546             for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); i++)
547             {
548                 const jfw::PluginLibrary & library = *i;
549                 jfw::VersionInfo versionInfo =
550                     aVendorSettings.getVersionInformation(library.sVendor);
551 
552                 osl::Module pluginLib(library.sPath);
553                 if (pluginLib.is() == sal_False)
554                     return JFW_E_NO_PLUGIN;
555                 //Check if the current plugin can detect JREs at the location
556                 // of the paths added by jfw_setJRELocations or jfw_addJRELocation
557                 //get the function from the plugin
558                 jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc =
559                     (jfw_plugin_getJavaInfoByPath_ptr) pluginLib.getFunctionSymbol(
560                         rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getJavaInfoByPath")));
561 
562                 OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc);
563                 if (jfw_plugin_getJavaInfoByPathFunc == NULL)
564                     return JFW_E_ERROR;
565 
566                 typedef std::vector<rtl::OUString>::const_iterator citLoc;
567                 for (citLoc it = vecJRELocations.begin();
568                     it != vecJRELocations.end(); it++)
569                 {
570                     jfw::CJavaInfo aInfo;
571                     javaPluginError err = (*jfw_plugin_getJavaInfoByPathFunc)(
572                         it->pData,
573                         library.sVendor.pData,
574                         versionInfo.sMinVersion.pData,
575                         versionInfo.sMaxVersion.pData,
576                         versionInfo.getExcludeVersions(),
577                         versionInfo.getExcludeVersionSize(),
578                         & aInfo.pInfo);
579                     if (err == JFW_PLUGIN_E_NO_JRE)
580                         continue;
581                     if (err == JFW_PLUGIN_E_FAILED_VERSION)
582                         continue;
583                     else if (err !=JFW_PLUGIN_E_NONE)
584                         return JFW_E_ERROR;
585 
586                     if (aInfo)
587                     {
588                         //We remember the very first installation in aCurrentInfo
589                         if (aCurrentInfo.getLocation().getLength() == 0)
590                             aCurrentInfo = aInfo;
591                         // compare features
592                         // If the user does not require any features (nFeatureFlags = 0)
593                         // then the first installation is used
594                         if ((aInfo.getFeatures() & nFeatureFlags) == nFeatureFlags)
595                         {
596                             //the just found Java implements all required features
597                             //currently there is only accessibility!!!
598                             aCurrentInfo = aInfo;
599                             bInfoFound = true;
600                             break;
601                         }
602                     }
603                 }//end iterate over paths
604                 if (bInfoFound == true)
605                     break;
606             }// end iterate plug-ins
607         }
608         if ((JavaInfo*) aCurrentInfo)
609         {
610             jfw::NodeJava javaNode;
611             javaNode.setJavaInfo(aCurrentInfo,true);
612             javaNode.write();
613 
614             if (pInfo !=NULL)
615             {
616                 //copy to out param
617                 *pInfo = aCurrentInfo.cloneJavaInfo();
618                 //remember that this JRE was selected in this process
619                 jfw::setJavaSelected();
620             }
621         }
622         else
623         {
624             errcode = JFW_E_NO_JAVA_FOUND;
625         }
626     }
627     catch (jfw::FrameworkException& e)
628     {
629         errcode = e.errorCode;
630         fprintf(stderr, "%s\n", e.message.getStr());
631         OSL_ENSURE(0, e.message.getStr());
632     }
633 
634     return errcode;
635 }
636 sal_Bool SAL_CALL jfw_areEqualJavaInfo(
637     JavaInfo const * pInfoA,JavaInfo const * pInfoB)
638 {
639     if (pInfoA == pInfoB)
640         return sal_True;
641     if (pInfoA == NULL || pInfoB == NULL)
642         return sal_False;
643     rtl::OUString sVendor(pInfoA->sVendor);
644     rtl::OUString sLocation(pInfoA->sLocation);
645     rtl::OUString sVersion(pInfoA->sVersion);
646     rtl::ByteSequence sData(pInfoA->arVendorData);
647     if (sVendor.equals(pInfoB->sVendor) == sal_True
648         && sLocation.equals(pInfoB->sLocation) == sal_True
649         && sVersion.equals(pInfoB->sVersion) == sal_True
650         && pInfoA->nFeatures == pInfoB->nFeatures
651         && pInfoA->nRequirements == pInfoB->nRequirements
652         && sData == pInfoB->arVendorData)
653     {
654         return sal_True;
655     }
656     return sal_False;
657 }
658 
659 
660 void SAL_CALL jfw_freeJavaInfo(JavaInfo *pInfo)
661 {
662     if (pInfo == NULL)
663         return;
664     rtl_uString_release(pInfo->sVendor);
665     rtl_uString_release(pInfo->sLocation);
666     rtl_uString_release(pInfo->sVersion);
667     rtl_byte_sequence_release(pInfo->arVendorData);
668     rtl_freeMemory(pInfo);
669 }
670 
671 javaFrameworkError SAL_CALL jfw_getSelectedJRE(JavaInfo **ppInfo)
672 {
673     javaFrameworkError errcode = JFW_E_NONE;
674     try
675     {
676         osl::MutexGuard guard(jfw::FwkMutex::get());
677         if (ppInfo == NULL)
678             return JFW_E_INVALID_ARG;
679 
680         if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
681         {
682             rtl::OUString sJRE = jfw::BootParams::getJREHome();
683 
684             jfw::CJavaInfo aInfo;
685             if ((errcode = jfw_getJavaInfoByPath(sJRE.pData, & aInfo.pInfo))
686                 != JFW_E_NONE)
687                 throw jfw::FrameworkException(
688                     JFW_E_CONFIGURATION,
689                     rtl::OString(
690                         "[Java framework] The JRE specified by the bootstrap "
691                         "variable UNO_JAVA_JFW_JREHOME  or  UNO_JAVA_JFW_ENV_JREHOME "
692                         " could not be recognized. Check the values and make sure that you "
693                         "use a plug-in library that can recognize that JRE."));
694 
695             *ppInfo = aInfo.detach();
696             return JFW_E_NONE;
697         }
698 
699         const jfw::MergedSettings settings;
700         jfw::CJavaInfo aInfo;
701         aInfo.attach(settings.createJavaInfo());
702         if (! aInfo)
703         {
704             *ppInfo = NULL;
705             return JFW_E_NONE;
706         }
707         //If the javavendors.xml has changed, then the current selected
708         //Java is not valid anymore
709         // /java/javaInfo/@vendorUpdate != javaSelection/updated (javavendors.xml)
710         rtl::OString sUpdated = jfw::getElementUpdated();
711 
712         if (sUpdated.equals(settings.getJavaInfoAttrVendorUpdate()) == sal_False)
713             return JFW_E_INVALID_SETTINGS;
714         *ppInfo = aInfo.detach();
715     }
716     catch (jfw::FrameworkException& e)
717     {
718         errcode = e.errorCode;
719         fprintf(stderr, "%s\n", e.message.getStr());
720         OSL_ENSURE(0, e.message.getStr());
721     }
722     return errcode;
723 }
724 
725 javaFrameworkError SAL_CALL jfw_isVMRunning(sal_Bool *bRunning)
726 {
727     osl::MutexGuard guard(jfw::FwkMutex::get());
728     if (bRunning == NULL)
729         return JFW_E_INVALID_ARG;
730     if (g_pJavaVM == NULL)
731         *bRunning = sal_False;
732     else
733         *bRunning = sal_True;
734     return JFW_E_NONE;
735 }
736 
737 javaFrameworkError SAL_CALL jfw_getJavaInfoByPath(
738     rtl_uString *pPath, JavaInfo **ppInfo)
739 {
740     javaFrameworkError errcode = JFW_E_NONE;
741     try
742     {
743         osl::MutexGuard guard(jfw::FwkMutex::get());
744         if (pPath == NULL || ppInfo == NULL)
745             return JFW_E_INVALID_ARG;
746 
747         jfw::VendorSettings aVendorSettings;
748         //Get a list of plugins which provide Java information
749         std::vector<jfw::PluginLibrary> vecPlugins =
750             aVendorSettings.getPluginData();
751         //Create a vector that holds the libraries, which will be later
752         //dynamically loaded;
753         boost::scoped_array<osl::Module> sarModules;
754         sarModules.reset(new osl::Module[vecPlugins.size()]);
755         osl::Module * arModules = sarModules.get();
756 
757         typedef std::vector<rtl::OUString>::const_iterator CIT_VENDOR;
758         std::vector<rtl::OUString> vecVendors =
759             aVendorSettings.getSupportedVendors();
760 
761         //Use every plug-in library to determine if the path represents a
762         //JRE. If a plugin recognized it then the loop will break
763         typedef std::vector<jfw::PluginLibrary>::const_iterator ci_pl;
764         int cModule = 0;
765         for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end();
766              i++, cModule++)
767         {
768             const jfw::PluginLibrary & library = *i;
769             jfw::VersionInfo versionInfo =
770                 aVendorSettings.getVersionInformation(library.sVendor);
771             arModules[cModule].load(library.sPath);
772             osl::Module & pluginLib = arModules[cModule];
773             if (pluginLib.is() == sal_False)
774             {
775                 rtl::OString msg = rtl::OUStringToOString(
776                     library.sPath, osl_getThreadTextEncoding());
777                 fprintf(stderr,"[jvmfwk] Could not load plugin %s\n" \
778                         "Modify the javavendors.xml accordingly!\n", msg.getStr());
779                 return JFW_E_NO_PLUGIN;
780             }
781 
782             jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc =
783                 (jfw_plugin_getJavaInfoByPath_ptr) pluginLib.getFunctionSymbol(
784                     rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getJavaInfoByPath")));
785 
786             OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc);
787             if (jfw_plugin_getJavaInfoByPathFunc == NULL)
788                 continue;
789 
790             //ask the plugin if this is a JRE.
791             //If so check if it meets the version requirements.
792             //Only if it does return a JavaInfo
793             JavaInfo* pInfo = NULL;
794             javaPluginError plerr = (*jfw_plugin_getJavaInfoByPathFunc)(
795                 pPath,
796                 library.sVendor.pData,
797                 versionInfo.sMinVersion.pData,
798                 versionInfo.sMaxVersion.pData,
799                 versionInfo.getExcludeVersions(),
800                 versionInfo.getExcludeVersionSize(),
801                 & pInfo);
802 
803             if (plerr == JFW_PLUGIN_E_NONE)
804             {
805                 //check if the vendor of the found JRE is supported
806                 if (vecVendors.size() == 0)
807                 {
808                     //vendor does not matter
809                     *ppInfo = pInfo;
810                     break;
811                 }
812                 else
813                 {
814                     rtl::OUString sVendor(pInfo->sVendor);
815                     CIT_VENDOR ivendor = std::find(vecVendors.begin(), vecVendors.end(),
816                                                    sVendor);
817                     if (ivendor != vecVendors.end())
818                     {
819                         *ppInfo = pInfo;
820                     }
821                     else
822                     {
823                         *ppInfo = NULL;
824                         errcode = JFW_E_NOT_RECOGNIZED;
825                     }
826                     break;
827                 }
828             }
829             else if(plerr == JFW_PLUGIN_E_FAILED_VERSION)
830             {//found JRE but it has the wrong version
831                 *ppInfo = NULL;
832                 errcode = JFW_E_FAILED_VERSION;
833                 break;
834             }
835             else if (plerr == JFW_PLUGIN_E_NO_JRE)
836             {// plugin does not recognize this path as belonging to JRE
837                 continue;
838             }
839             OSL_ASSERT(0);
840         }
841         if (*ppInfo == NULL && errcode != JFW_E_FAILED_VERSION)
842             errcode = JFW_E_NOT_RECOGNIZED;
843     }
844     catch (jfw::FrameworkException& e)
845     {
846         errcode = e.errorCode;
847         fprintf(stderr, "%s\n", e.message.getStr());
848         OSL_ENSURE(0, e.message.getStr());
849     }
850 
851     return errcode;
852 }
853 
854 
855 javaFrameworkError SAL_CALL jfw_setSelectedJRE(JavaInfo const *pInfo)
856 {
857     javaFrameworkError errcode = JFW_E_NONE;
858     try
859     {
860         osl::MutexGuard guard(jfw::FwkMutex::get());
861         if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
862             return JFW_E_DIRECT_MODE;
863         //check if pInfo is the selected JRE
864         JavaInfo *currentInfo = NULL;
865         errcode = jfw_getSelectedJRE( & currentInfo);
866         if (errcode != JFW_E_NONE && errcode != JFW_E_INVALID_SETTINGS)
867             return errcode;
868 
869         if (jfw_areEqualJavaInfo(currentInfo, pInfo) == sal_False)
870         {
871             jfw::NodeJava node;
872             node.setJavaInfo(pInfo, false);
873             node.write();
874             //remember that the JRE was selected in this process
875             jfw::setJavaSelected();
876         }
877     }
878     catch (jfw::FrameworkException& e)
879     {
880         errcode = e.errorCode;
881         fprintf(stderr, "%s\n", e.message.getStr());
882         OSL_ENSURE(0, e.message.getStr());
883     }
884     return errcode;
885 }
886 javaFrameworkError SAL_CALL jfw_setEnabled(sal_Bool bEnabled)
887 {
888     javaFrameworkError errcode = JFW_E_NONE;
889     try
890     {
891         osl::MutexGuard guard(jfw::FwkMutex::get());
892         if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
893             return JFW_E_DIRECT_MODE;
894 
895         if (g_bEnabledSwitchedOn == false && bEnabled == sal_True)
896         {
897             //When the process started then Enabled was false.
898             //This is first time enabled is set to true.
899             //That means, no preparational work has been done, such as setting the
900             //LD_LIBRARY_PATH, etc.
901 
902             //check if Enabled is false;
903             const jfw::MergedSettings settings;
904             if (settings.getEnabled() == sal_False)
905                 g_bEnabledSwitchedOn = true;
906         }
907         jfw::NodeJava node;
908         node.setEnabled(bEnabled);
909         node.write();
910     }
911     catch (jfw::FrameworkException& e)
912     {
913         errcode = e.errorCode;
914         fprintf(stderr, "%s\n", e.message.getStr());
915         OSL_ENSURE(0, e.message.getStr());
916     }
917     return errcode;
918 }
919 
920 javaFrameworkError SAL_CALL jfw_getEnabled(sal_Bool *pbEnabled)
921 {
922     javaFrameworkError errcode = JFW_E_NONE;
923     try
924     {
925         if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
926             return JFW_E_DIRECT_MODE;
927         osl::MutexGuard guard(jfw::FwkMutex::get());
928         if (pbEnabled == NULL)
929             return JFW_E_INVALID_ARG;
930         jfw::MergedSettings settings;
931         *pbEnabled = settings.getEnabled();
932     }
933     catch (jfw::FrameworkException& e)
934     {
935         errcode = e.errorCode;
936         fprintf(stderr, "%s\n", e.message.getStr());
937         OSL_ENSURE(0, e.message.getStr());
938     }
939     return errcode;
940 }
941 
942 
943 javaFrameworkError SAL_CALL jfw_setVMParameters(
944     rtl_uString * * arOptions, sal_Int32 nLen)
945 {
946     javaFrameworkError errcode = JFW_E_NONE;
947     try
948     {
949         osl::MutexGuard guard(jfw::FwkMutex::get());
950         if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
951             return JFW_E_DIRECT_MODE;
952         jfw::NodeJava node;
953         if (arOptions == NULL && nLen != 0)
954             return JFW_E_INVALID_ARG;
955         node.setVmParameters(arOptions, nLen);
956         node.write();
957     }
958     catch (jfw::FrameworkException& e)
959     {
960         errcode = e.errorCode;
961         fprintf(stderr, "%s\n", e.message.getStr());
962         OSL_ENSURE(0, e.message.getStr());
963     }
964 
965     return errcode;
966 }
967 
968 javaFrameworkError SAL_CALL jfw_getVMParameters(
969     rtl_uString *** parOptions, sal_Int32 * pLen)
970 {
971     javaFrameworkError errcode = JFW_E_NONE;
972     try
973     {
974         osl::MutexGuard guard(jfw::FwkMutex::get());
975         if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
976             return JFW_E_DIRECT_MODE;
977 
978         if (parOptions == NULL || pLen == NULL)
979             return JFW_E_INVALID_ARG;
980         const jfw::MergedSettings settings;
981         settings.getVmParametersArray(parOptions, pLen);
982     }
983     catch (jfw::FrameworkException& e)
984     {
985         errcode = e.errorCode;
986         fprintf(stderr, "%s\n", e.message.getStr());
987         OSL_ENSURE(0, e.message.getStr());
988     }
989     return errcode;
990 }
991 
992 javaFrameworkError SAL_CALL jfw_setUserClassPath(rtl_uString * pCp)
993 {
994     javaFrameworkError errcode = JFW_E_NONE;
995     try
996     {
997         osl::MutexGuard guard(jfw::FwkMutex::get());
998         if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
999             return JFW_E_DIRECT_MODE;
1000         jfw::NodeJava node;
1001         if (pCp == NULL)
1002             return JFW_E_INVALID_ARG;
1003         node.setUserClassPath(pCp);
1004         node.write();
1005     }
1006     catch (jfw::FrameworkException& e)
1007     {
1008         errcode = e.errorCode;
1009         fprintf(stderr, "%s\n", e.message.getStr());
1010         OSL_ENSURE(0, e.message.getStr());
1011     }
1012     return errcode;
1013 }
1014 
1015 javaFrameworkError SAL_CALL jfw_getUserClassPath(rtl_uString ** ppCP)
1016 {
1017     javaFrameworkError errcode = JFW_E_NONE;
1018     try
1019     {
1020         osl::MutexGuard guard(jfw::FwkMutex::get());
1021         if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
1022             return JFW_E_DIRECT_MODE;
1023         if (ppCP == NULL)
1024             return JFW_E_INVALID_ARG;
1025         const jfw::MergedSettings settings;
1026         *ppCP = settings.getUserClassPath().pData;
1027         rtl_uString_acquire(*ppCP);
1028     }
1029     catch (jfw::FrameworkException& e)
1030     {
1031         errcode = e.errorCode;
1032         fprintf(stderr, "%s\n", e.message.getStr());
1033         OSL_ENSURE(0, e.message.getStr());
1034     }
1035     return errcode;
1036 }
1037 
1038 javaFrameworkError SAL_CALL jfw_addJRELocation(rtl_uString * sLocation)
1039 {
1040     javaFrameworkError errcode = JFW_E_NONE;
1041     try
1042     {
1043         osl::MutexGuard guard(jfw::FwkMutex::get());
1044         if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
1045             return JFW_E_DIRECT_MODE;
1046         jfw::NodeJava node;
1047         if (sLocation == NULL)
1048             return JFW_E_INVALID_ARG;
1049         node.load();
1050         node.addJRELocation(sLocation);
1051         node.write();
1052     }
1053     catch (jfw::FrameworkException& e)
1054     {
1055         errcode = e.errorCode;
1056         fprintf(stderr, "%s\n", e.message.getStr());
1057         OSL_ENSURE(0, e.message.getStr());
1058     }
1059 
1060     return errcode;
1061 
1062 }
1063 
1064 javaFrameworkError SAL_CALL jfw_setJRELocations(
1065     rtl_uString ** arLocations, sal_Int32 nLen)
1066 {
1067     javaFrameworkError errcode = JFW_E_NONE;
1068     try
1069     {
1070         osl::MutexGuard guard(jfw::FwkMutex::get());
1071         if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
1072             return JFW_E_DIRECT_MODE;
1073         jfw::NodeJava node;
1074         if (arLocations == NULL && nLen != 0)
1075             return JFW_E_INVALID_ARG;
1076         node.setJRELocations(arLocations, nLen);
1077         node.write();
1078     }
1079     catch (jfw::FrameworkException& e)
1080     {
1081         errcode = e.errorCode;
1082         fprintf(stderr, "%s\n", e.message.getStr());
1083         OSL_ENSURE(0, e.message.getStr());
1084     }
1085     return errcode;
1086 
1087 }
1088 
1089 javaFrameworkError SAL_CALL jfw_getJRELocations(
1090     rtl_uString *** parLocations, sal_Int32 *pLen)
1091 {
1092     javaFrameworkError errcode = JFW_E_NONE;
1093     try
1094     {
1095         osl::MutexGuard guard(jfw::FwkMutex::get());
1096         if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
1097             return JFW_E_DIRECT_MODE;
1098 
1099         if (parLocations == NULL || pLen == NULL)
1100             return JFW_E_INVALID_ARG;
1101         const jfw::MergedSettings settings;
1102         settings.getJRELocations(parLocations, pLen);
1103     }
1104     catch (jfw::FrameworkException& e)
1105     {
1106         errcode = e.errorCode;
1107         fprintf(stderr, "%s\n", e.message.getStr());
1108         OSL_ENSURE(0, e.message.getStr());
1109     }
1110 
1111     return errcode;
1112 }
1113 
1114 
1115 javaFrameworkError jfw_existJRE(const JavaInfo *pInfo, sal_Bool *exist)
1116 {
1117     //get the function jfw_plugin_existJRE
1118     jfw::VendorSettings aVendorSettings;
1119     jfw::CJavaInfo aInfo;
1120     aInfo = (const ::JavaInfo*) pInfo; //makes a copy of pInfo
1121     rtl::OUString sLibPath = aVendorSettings.getPluginLibrary(aInfo.getVendor());
1122     osl::Module modulePlugin(sLibPath);
1123     if ( ! modulePlugin)
1124         return JFW_E_NO_PLUGIN;
1125     rtl::OUString sFunctionName(
1126         RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_existJRE"));
1127     jfw_plugin_existJRE_ptr pFunc =
1128         (jfw_plugin_existJRE_ptr)
1129         osl_getFunctionSymbol(modulePlugin, sFunctionName.pData);
1130     if (pFunc == NULL)
1131         return JFW_E_ERROR;
1132 
1133     javaPluginError plerr = (*pFunc)(pInfo, exist);
1134 
1135     javaFrameworkError ret = JFW_E_NONE;
1136     switch (plerr)
1137     {
1138     case JFW_PLUGIN_E_NONE:
1139         ret = JFW_E_NONE;
1140         break;
1141     case JFW_PLUGIN_E_INVALID_ARG:
1142         ret = JFW_E_INVALID_ARG;
1143         break;
1144     case JFW_PLUGIN_E_ERROR:
1145         ret = JFW_E_ERROR;
1146         break;
1147     default:
1148         ret = JFW_E_ERROR;
1149     }
1150     return ret;
1151 }
1152 
1153 void SAL_CALL jfw_lock()
1154 {
1155     jfw::FwkMutex::get().acquire();
1156 }
1157 
1158 void SAL_CALL jfw_unlock()
1159 {
1160     jfw::FwkMutex::get().release();
1161 }
1162 
1163 
1164 namespace jfw
1165 {
1166 CJavaInfo::CJavaInfo(): pInfo(0)
1167 {
1168 }
1169 
1170 CJavaInfo::CJavaInfo(const CJavaInfo & info)
1171 {
1172     pInfo = copyJavaInfo(info.pInfo);
1173 }
1174 
1175 CJavaInfo::CJavaInfo(::JavaInfo * info, _transfer_ownership)
1176 {
1177     pInfo = info;
1178 }
1179 CJavaInfo CJavaInfo::createWrapper(::JavaInfo* info)
1180 {
1181     return CJavaInfo(info, TRANSFER);
1182 }
1183 void CJavaInfo::attach(::JavaInfo * info)
1184 {
1185     jfw_freeJavaInfo(pInfo);
1186     pInfo = info;
1187 }
1188 ::JavaInfo * CJavaInfo::detach()
1189 {
1190     JavaInfo * tmp = pInfo;
1191     pInfo = NULL;
1192     return tmp;
1193 }
1194 
1195 CJavaInfo::~CJavaInfo()
1196 {
1197     jfw_freeJavaInfo(pInfo);
1198 }
1199 
1200 CJavaInfo::operator ::JavaInfo* ()
1201 {
1202     return pInfo;
1203 }
1204 
1205 JavaInfo * CJavaInfo::copyJavaInfo(const JavaInfo * pInfo)
1206 {
1207     if (pInfo == NULL)
1208         return NULL;
1209     JavaInfo* newInfo =
1210           (JavaInfo*) rtl_allocateMemory(sizeof(JavaInfo));
1211     if (newInfo)
1212     {
1213         rtl_copyMemory(newInfo, pInfo, sizeof(JavaInfo));
1214         rtl_uString_acquire(pInfo->sVendor);
1215         rtl_uString_acquire(pInfo->sLocation);
1216         rtl_uString_acquire(pInfo->sVersion);
1217         rtl_byte_sequence_acquire(pInfo->arVendorData);
1218     }
1219     return newInfo;
1220 }
1221 
1222 
1223 JavaInfo* CJavaInfo::cloneJavaInfo() const
1224 {
1225     if (pInfo == NULL)
1226         return NULL;
1227     return copyJavaInfo(pInfo);
1228 }
1229 
1230 CJavaInfo & CJavaInfo::operator = (const CJavaInfo& info)
1231 {
1232     if (&info == this)
1233         return *this;
1234 
1235     jfw_freeJavaInfo(pInfo);
1236     pInfo = copyJavaInfo(info.pInfo);
1237     return *this;
1238 }
1239 CJavaInfo & CJavaInfo::operator = (const ::JavaInfo* info)
1240 {
1241     if (info == pInfo)
1242         return *this;
1243 
1244     jfw_freeJavaInfo(pInfo);
1245     pInfo = copyJavaInfo(info);
1246     return *this;
1247 }
1248 
1249 const ::JavaInfo* CJavaInfo::operator ->() const
1250 {
1251     return pInfo;
1252 }
1253 
1254 CJavaInfo::operator JavaInfo const * () const
1255 {
1256     return pInfo;
1257 }
1258 // ::JavaInfo** CJavaInfo::operator & ()
1259 // {
1260 //     return & pInfo;
1261 // }
1262 
1263 rtl::OUString CJavaInfo::getVendor() const
1264 {
1265     if (pInfo)
1266         return rtl::OUString(pInfo->sVendor);
1267     else
1268         return rtl::OUString();
1269 }
1270 
1271 rtl::OUString CJavaInfo::getLocation() const
1272 {
1273     if (pInfo)
1274         return rtl::OUString(pInfo->sLocation);
1275     else
1276         return rtl::OUString();
1277 }
1278 
1279 sal_uInt64 CJavaInfo::getFeatures() const
1280 {
1281     if (pInfo)
1282         return pInfo->nFeatures;
1283     else
1284         return 0l;
1285 }
1286 
1287 }
1288