merge the formfield patch from ooo-build
[ooovba.git] / jvmfwk / source / framework.cxx
blobd271a66833a3c3f1dc6971b13548cd7a66148c20
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: framework.cxx,v $
10 * $Revision: 1.30 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_jvmfwk.hxx"
33 #include "boost/scoped_array.hpp"
34 #include "rtl/ustring.hxx"
35 #include "rtl/bootstrap.hxx"
36 #include "osl/thread.hxx"
37 #include "osl/file.hxx"
38 #include "osl/module.hxx"
39 #include "jvmfwk/framework.h"
40 #include "jvmfwk/vendorplugin.h"
41 #include <vector>
42 #include <functional>
43 #include <algorithm>
44 #include "framework.hxx"
45 #include "fwkutil.hxx"
46 #include "elements.hxx"
47 #include "fwkbase.hxx"
49 #ifdef WNT
50 /** The existence of the file useatjava.txt decides if a Java should be used
51 that supports accessibility tools.
53 #define USE_ACCESSIBILITY_FILE "useatjava.txt"
54 #endif
56 #define UNO_JAVA_JFW_JREHOME "UNO_JAVA_JFW_JREHOME"
57 namespace {
58 JavaVM * g_pJavaVM = NULL;
60 bool g_bEnabledSwitchedOn = false;
62 sal_Bool areEqualJavaInfo(
63 JavaInfo const * pInfoA,JavaInfo const * pInfoB)
65 return jfw_areEqualJavaInfo(pInfoA, pInfoB);
69 javaFrameworkError SAL_CALL jfw_findAllJREs(JavaInfo ***pparInfo, sal_Int32 *pSize)
71 javaFrameworkError retVal = JFW_E_NONE;
72 try
74 osl::MutexGuard guard(jfw::FwkMutex::get());
75 javaFrameworkError errcode = JFW_E_NONE;
76 if (pparInfo == NULL || pSize == NULL)
77 return JFW_E_INVALID_ARG;
79 jfw::VendorSettings aVendorSettings;
80 //Get a list of plugins which provide Java information
81 std::vector<jfw::PluginLibrary> vecPlugins =
82 aVendorSettings.getPluginData();
84 //Create a vector that holds the libraries, which will be later
85 //dynamically loaded;
86 boost::scoped_array<osl::Module> sarModules;
87 sarModules.reset(new osl::Module[vecPlugins.size()]);
88 osl::Module * arModules = sarModules.get();
89 //Add the JavaInfos found by jfw_plugin_getAllJavaInfos to the vector
90 //Make sure that the contents are destroyed if this
91 //function returns with an error
92 std::vector<jfw::CJavaInfo> vecInfo;
93 //Add the JavaInfos found by jfw_plugin_getJavaInfoByPath to this vector
94 //Make sure that the contents are destroyed if this
95 //function returns with an error
96 std::vector<jfw::CJavaInfo> vecInfoManual;
97 typedef std::vector<jfw::CJavaInfo>::iterator it_info;
98 //get the list of paths to jre locations which have been
99 //added manually
100 const jfw::MergedSettings settings;
101 const std::vector<rtl::OUString>& vecJRELocations =
102 settings.getJRELocations();
103 //Use every plug-in library to get Java installations.
104 typedef std::vector<jfw::PluginLibrary>::const_iterator ci_pl;
105 int cModule = 0;
106 for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); i++, cModule++)
108 const jfw::PluginLibrary & library = *i;
109 jfw::VersionInfo versionInfo =
110 aVendorSettings.getVersionInformation(library.sVendor);
111 arModules[cModule].load(library.sPath);
112 osl::Module & pluginLib = arModules[cModule];
114 if (pluginLib.is() == sal_False)
116 rtl::OString msg = rtl::OUStringToOString(
117 library.sPath, osl_getThreadTextEncoding());
118 fprintf(stderr,"[jvmfwk] Could not load plugin %s\n" \
119 "Modify the javavendors.xml accordingly!\n", msg.getStr());
120 return JFW_E_NO_PLUGIN;
122 jfw_plugin_getAllJavaInfos_ptr getAllJavaFunc =
123 (jfw_plugin_getAllJavaInfos_ptr) pluginLib.getFunctionSymbol(
124 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getAllJavaInfos")));
126 OSL_ASSERT(getAllJavaFunc);
127 if (getAllJavaFunc == NULL)
128 return JFW_E_ERROR;
130 //get all installations of one vendor according to minVersion,
131 //maxVersion and excludeVersions
132 sal_Int32 cInfos = 0;
133 JavaInfo** arInfos = NULL;
134 javaPluginError plerr = (*getAllJavaFunc)(
135 library.sVendor.pData,
136 versionInfo.sMinVersion.pData,
137 versionInfo.sMaxVersion.pData,
138 versionInfo.getExcludeVersions(),
139 versionInfo.getExcludeVersionSize(),
140 & arInfos,
141 & cInfos);
143 if (plerr != JFW_PLUGIN_E_NONE)
144 return JFW_E_ERROR;
146 for (int j = 0; j < cInfos; j++)
147 vecInfo.push_back(jfw::CJavaInfo::createWrapper(arInfos[j]));
149 rtl_freeMemory(arInfos);
151 //Check if the current plugin can detect JREs at the location
152 // of the paths added by jfw_setJRELocations or jfw_addJRELocation
153 //get the function from the plugin
154 jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc =
155 (jfw_plugin_getJavaInfoByPath_ptr) pluginLib.getFunctionSymbol(
156 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getJavaInfoByPath")));
158 OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc);
159 if (jfw_plugin_getJavaInfoByPathFunc == NULL)
160 return JFW_E_ERROR;
162 typedef std::vector<rtl::OUString>::const_iterator citLoc;
163 //Check every manually added location
164 for (citLoc ii = vecJRELocations.begin();
165 ii != vecJRELocations.end(); ii++)
167 // rtl::OUString sLocation =
168 // rtl::OStringToOUString(*ii, RTL_TEXTENCODING_UTF8);
169 jfw::CJavaInfo aInfo;
170 plerr = (*jfw_plugin_getJavaInfoByPathFunc)(
171 ii->pData,
172 library.sVendor.pData,
173 versionInfo.sMinVersion.pData,
174 versionInfo.sMaxVersion.pData,
175 versionInfo.getExcludeVersions(),
176 versionInfo.getExcludeVersionSize(),
177 & aInfo.pInfo);
178 if (plerr == JFW_PLUGIN_E_NO_JRE)
179 continue;
180 if (plerr == JFW_PLUGIN_E_FAILED_VERSION)
181 continue;
182 else if (plerr !=JFW_PLUGIN_E_NONE)
183 return JFW_E_ERROR;
185 if (aInfo)
187 //Was this JRE already added?. Different plugins could detect
188 //the same JRE
189 it_info it_duplicate =
190 std::find_if(vecInfoManual.begin(), vecInfoManual.end(),
191 std::bind2nd(std::ptr_fun(areEqualJavaInfo), aInfo));
192 if (it_duplicate == vecInfoManual.end())
193 vecInfoManual.push_back(aInfo);
197 //Make sure vecInfoManual contains only JavaInfos for the vendors for which
198 //there is a javaSelection/plugins/library entry in the javavendors.xml
199 //To obtain the JavaInfos for the manually added JRE locations the function
200 //jfw_getJavaInfoByPath is called which can return a JavaInfo of any vendor.
201 std::vector<jfw::CJavaInfo> vecInfoManual2;
202 for (it_info ivm = vecInfoManual.begin(); ivm != vecInfoManual.end(); ivm++)
204 for (ci_pl ii = vecPlugins.begin(); ii != vecPlugins.end(); ii++)
206 if ( ii->sVendor.equals((*ivm)->sVendor))
208 vecInfoManual2.push_back(*ivm);
209 break;
213 //Check which JavaInfo from vector vecInfoManual2 is already
214 //contained in vecInfo. If it already exists then remove it from
215 //vecInfoManual2
216 for (it_info j = vecInfo.begin(); j != vecInfo.end(); j++)
218 it_info it_duplicate =
219 std::find_if(vecInfoManual2.begin(), vecInfoManual2.end(),
220 std::bind2nd(std::ptr_fun(areEqualJavaInfo), *j));
221 if (it_duplicate != vecInfoManual2.end())
222 vecInfoManual2.erase(it_duplicate);
224 //create an fill the array of JavaInfo*
225 sal_Int32 nSize = vecInfo.size() + vecInfoManual2.size();
226 *pparInfo = (JavaInfo**) rtl_allocateMemory(
227 nSize * sizeof(JavaInfo*));
228 if (*pparInfo == NULL)
229 return JFW_E_ERROR;
231 typedef std::vector<jfw::CJavaInfo>::iterator it;
232 int index = 0;
233 //Add the automatically detected JREs
234 for (it k = vecInfo.begin(); k != vecInfo.end(); k++)
235 (*pparInfo)[index++] = k->detach();
236 //Add the manually detected JREs
237 for (it l = vecInfoManual2.begin(); l != vecInfoManual2.end(); l++)
238 (*pparInfo)[index++] = l->detach();
240 *pSize = nSize;
241 return errcode;
243 catch (jfw::FrameworkException& e)
245 retVal = e.errorCode;
246 fprintf(stderr, "%s\n", e.message.getStr());
247 OSL_ENSURE(0, e.message.getStr());
249 return retVal;
252 javaFrameworkError SAL_CALL jfw_startVM(JavaVMOption *arOptions, sal_Int32 cOptions,
253 JavaVM **ppVM, JNIEnv **ppEnv)
255 #ifndef SOLAR_JAVA
256 return JFW_E_ERROR;
257 #else
258 javaFrameworkError errcode = JFW_E_NONE;
259 if (cOptions > 0 && arOptions == NULL)
260 return JFW_E_INVALID_ARG;
264 osl::MutexGuard guard(jfw::FwkMutex::get());
266 //We keep this pointer so we can determine if a VM has already
267 //been created.
268 if (g_pJavaVM != NULL)
269 return JFW_E_RUNNING_JVM;
271 if (ppVM == NULL)
272 return JFW_E_INVALID_ARG;
274 std::vector<rtl::OString> vmParams;
275 rtl::OString sUserClassPath;
276 jfw::CJavaInfo aInfo;
277 jfw::JFW_MODE mode = jfw::getMode();
278 if (mode == jfw::JFW_MODE_APPLICATION)
280 const jfw::MergedSettings settings;
281 if (sal_False == settings.getEnabled())
282 return JFW_E_JAVA_DISABLED;
283 aInfo.attach(settings.createJavaInfo());
284 //check if a Java has ever been selected
285 if (aInfo == NULL)
286 return JFW_E_NO_SELECT;
288 #ifdef WNT
289 //Because on Windows there is no system setting that we can use to determine
290 //if Assistive Technology Tool support is needed, we ship a .reg file that the
291 //user can use to create a registry setting. When the user forgets to set
292 //the key before he starts the office then a JRE may be selected without access bridge.
293 //When he later sets the key then we select a JRE with accessibility support but
294 //only if the user has not manually changed the selected JRE in the options dialog.
295 if (jfw::isAccessibilitySupportDesired())
297 // If no JRE has been selected then we do not select one. This function shall then
298 //return JFW_E_NO_SELECT
299 if (aInfo != NULL &&
300 (aInfo->nFeatures & JFW_FEATURE_ACCESSBRIDGE) == 0)
302 //has the user manually selected a JRE?
303 if (settings.getJavaInfoAttrAutoSelect() == true)
305 // if not then the automatism has previously selected a JRE
306 //without accessibility support. We return JFW_E_NO_SELECT
307 //to cause that we search for another JRE. The search code will
308 //then prefer a JRE with accessibility support.
309 return JFW_E_NO_SELECT;
313 #endif
314 //check if the javavendors.xml has changed after a Java was selected
315 rtl::OString sVendorUpdate = jfw::getElementUpdated();
317 if (sVendorUpdate != settings.getJavaInfoAttrVendorUpdate())
318 return JFW_E_INVALID_SETTINGS;
320 //check if JAVA is disabled
321 //If Java is enabled, but it was disabled when this process was started
322 // then no preparational work, such as setting the LD_LIBRARY_PATH, was
323 //done. Therefore if a JRE needs it it must not be started.
324 if (g_bEnabledSwitchedOn &&
325 (aInfo->nRequirements & JFW_REQUIRE_NEEDRESTART))
326 return JFW_E_NEED_RESTART;
328 //Check if the selected Java was set in this process. If so it
329 //must not have the requirments flag JFW_REQUIRE_NEEDRESTART
330 if ((aInfo->nRequirements & JFW_REQUIRE_NEEDRESTART)
332 (jfw::wasJavaSelectedInSameProcess() == true))
333 return JFW_E_NEED_RESTART;
335 vmParams = settings.getVmParametersUtf8();
336 sUserClassPath = jfw::makeClassPathOption(settings.getUserClassPath());
337 } // end mode FWK_MODE_OFFICE
338 else if (mode == jfw::JFW_MODE_DIRECT)
340 errcode = jfw_getSelectedJRE(&aInfo.pInfo);
341 if (errcode != JFW_E_NONE)
342 return errcode;
343 //In direct mode the options are specified by bootstrap variables
344 //of the form UNO_JAVA_JFW_PARAMETER_1 .. UNO_JAVA_JFW_PARAMETER_n
345 vmParams = jfw::BootParams::getVMParameters();
346 sUserClassPath =
347 "-Djava.class.path=" + jfw::BootParams::getClasspath();
349 else
350 OSL_ASSERT(0);
352 //get the function jfw_plugin_startJavaVirtualMachine
353 jfw::VendorSettings aVendorSettings;
354 rtl::OUString sLibPath = aVendorSettings.getPluginLibrary(aInfo.getVendor());
356 osl::Module modulePlugin(sLibPath);
357 if ( ! modulePlugin)
358 return JFW_E_NO_PLUGIN;
360 rtl::OUString sFunctionName(
361 RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_startJavaVirtualMachine"));
362 jfw_plugin_startJavaVirtualMachine_ptr pFunc =
363 (jfw_plugin_startJavaVirtualMachine_ptr)
364 osl_getFunctionSymbol(modulePlugin, sFunctionName.pData);
365 if (pFunc == NULL)
366 return JFW_E_ERROR;
368 // create JavaVMOptions array that is passed to the plugin
369 // it contains the classpath and all options set in the
370 //options dialog
371 boost::scoped_array<JavaVMOption> sarJOptions(
372 new JavaVMOption[cOptions + 2 + vmParams.size()]);
373 JavaVMOption * arOpt = sarJOptions.get();
374 if (! arOpt)
375 return JFW_E_ERROR;
377 //The first argument is the classpath
378 arOpt[0].optionString= (char*) sUserClassPath.getStr();
379 arOpt[0].extraInfo = NULL;
380 // Set a flag that this JVM has been created via the JNI Invocation API
381 // (used, for example, by UNO remote bridges to share a common thread pool
382 // factory among Java and native bridge implementations):
383 arOpt[1].optionString = (char *) "-Dorg.openoffice.native=";
384 arOpt[1].extraInfo = 0;
386 //add the options set by options dialog
387 int index = 2;
388 typedef std::vector<rtl::OString>::const_iterator cit;
389 for (cit i = vmParams.begin(); i != vmParams.end(); i ++)
391 arOpt[index].optionString = const_cast<sal_Char*>(i->getStr());
392 arOpt[index].extraInfo = 0;
393 index ++;
395 //add all options of the arOptions argument
396 for (int ii = 0; ii < cOptions; ii++)
398 arOpt[index].optionString = arOptions[ii].optionString;
399 arOpt[index].extraInfo = arOptions[ii].extraInfo;
400 index++;
403 //start Java
404 JavaVM *pVm = NULL;
405 javaPluginError plerr = (*pFunc)(aInfo, arOpt, index, & pVm, ppEnv);
406 if (plerr == JFW_PLUGIN_E_VM_CREATION_FAILED)
408 errcode = JFW_E_VM_CREATION_FAILED;
410 else if (plerr != JFW_PLUGIN_E_NONE )
412 errcode = JFW_E_ERROR;
414 else
416 g_pJavaVM = pVm;
417 *ppVM = pVm;
419 OSL_ASSERT(plerr != JFW_PLUGIN_E_WRONG_VENDOR);
421 catch (jfw::FrameworkException& e)
423 errcode = e.errorCode;
424 fprintf(stderr, "%s\n", e.message.getStr());
425 OSL_ENSURE(0, e.message.getStr());
428 return errcode;
429 #endif
432 /** We do not use here jfw_findAllJREs and then check if a JavaInfo
433 meets the requirements, because that means using all plug-ins, which
434 may take quite a while. The implementation uses one plug-in and if
435 it already finds a suitable JRE then it is done and does not need to
436 load another plug-in
438 javaFrameworkError SAL_CALL jfw_findAndSelectJRE(JavaInfo **pInfo)
440 javaFrameworkError errcode = JFW_E_NONE;
443 osl::MutexGuard guard(jfw::FwkMutex::get());
444 if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
445 return JFW_E_DIRECT_MODE;
446 sal_uInt64 nFeatureFlags = 0;
447 jfw::CJavaInfo aCurrentInfo;
448 //Determine if accessibility support is needed
449 bool bSupportAccessibility = jfw::isAccessibilitySupportDesired();
450 nFeatureFlags = bSupportAccessibility ?
451 JFW_FEATURE_ACCESSBRIDGE : 0L;
453 //Get a list of services which provide Java information
454 jfw::VendorSettings aVendorSettings;
455 std::vector<jfw::PluginLibrary> vecPlugins =
456 aVendorSettings.getPluginData();
457 //Create a vector that holds the libraries, which will be later
458 //dynamically loaded;
459 boost::scoped_array<osl::Module> sarModules;
460 sarModules.reset(new osl::Module[vecPlugins.size()]);
461 osl::Module * arModules = sarModules.get();
463 //Use every plug-in library to get Java installations. At the first usable
464 //Java the loop will break
465 typedef std::vector<jfw::PluginLibrary>::const_iterator ci_pl;
466 int cModule = 0;
467 for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); i++, cModule++)
469 const jfw::PluginLibrary & library = *i;
470 jfw::VersionInfo versionInfo =
471 aVendorSettings.getVersionInformation(library.sVendor);
473 arModules[cModule].load(library.sPath);
474 osl::Module & pluginLib = arModules[cModule];
475 if (pluginLib.is() == sal_False)
476 return JFW_E_NO_PLUGIN;
478 jfw_plugin_getAllJavaInfos_ptr getAllJavaFunc =
479 (jfw_plugin_getAllJavaInfos_ptr) pluginLib.getFunctionSymbol(
480 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getAllJavaInfos")));
482 OSL_ASSERT(getAllJavaFunc);
483 if (getAllJavaFunc == NULL)
484 continue;
486 //get all installations of one vendor according to minVersion,
487 //maxVersion and excludeVersions
488 sal_Int32 cInfos = 0;
489 JavaInfo** arInfos = NULL;
490 javaPluginError plerr = (*getAllJavaFunc)(
491 library.sVendor.pData,
492 versionInfo.sMinVersion.pData,
493 versionInfo.sMaxVersion.pData,
494 versionInfo.getExcludeVersions(),
495 versionInfo.getExcludeVersionSize(),
496 & arInfos,
497 & cInfos);
499 if (plerr != JFW_PLUGIN_E_NONE)
500 continue;
501 //iterate over all installations to find the best which has
502 //all features
503 if (cInfos == 0)
505 rtl_freeMemory(arInfos);
506 continue;
508 bool bInfoFound = false;
509 for (int ii = 0; ii < cInfos; ii++)
511 JavaInfo* pJInfo = arInfos[ii];
513 //We remember the very first installation in aCurrentInfo
514 if (aCurrentInfo.getLocation().getLength() == 0)
515 aCurrentInfo = pJInfo;
516 // compare features
517 // If the user does not require any features (nFeatureFlags = 0)
518 // then the first installation is used
519 if ((pJInfo->nFeatures & nFeatureFlags) == nFeatureFlags)
521 //the just found Java implements all required features
522 //currently there is only accessibility!!!
523 aCurrentInfo = pJInfo;
524 bInfoFound = true;
525 break;
528 //The array returned by jfw_plugin_getAllJavaInfos must be freed as well as
529 //its contents
530 for (int j = 0; j < cInfos; j++)
531 jfw_freeJavaInfo(arInfos[j]);
532 rtl_freeMemory(arInfos);
534 if (bInfoFound == true)
535 break;
536 //All Java installations found by the current plug-in lib
537 //do not provide the required features. Try the next plug-in
539 if ((JavaInfo*) aCurrentInfo == NULL)
540 {//The plug-ins did not find a suitable Java. Now try the paths which have been
541 //added manually.
542 //get the list of paths to jre locations which have been added manually
543 const jfw::MergedSettings settings;
544 //node.loadFromSettings();
545 const std::vector<rtl::OUString> & vecJRELocations =
546 settings.getJRELocations();
547 //use every plug-in to determine the JavaInfo objects
548 bool bInfoFound = false;
549 for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); i++)
551 const jfw::PluginLibrary & library = *i;
552 jfw::VersionInfo versionInfo =
553 aVendorSettings.getVersionInformation(library.sVendor);
555 osl::Module pluginLib(library.sPath);
556 if (pluginLib.is() == sal_False)
557 return JFW_E_NO_PLUGIN;
558 //Check if the current plugin can detect JREs at the location
559 // of the paths added by jfw_setJRELocations or jfw_addJRELocation
560 //get the function from the plugin
561 jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc =
562 (jfw_plugin_getJavaInfoByPath_ptr) pluginLib.getFunctionSymbol(
563 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getJavaInfoByPath")));
565 OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc);
566 if (jfw_plugin_getJavaInfoByPathFunc == NULL)
567 return JFW_E_ERROR;
569 typedef std::vector<rtl::OUString>::const_iterator citLoc;
570 for (citLoc it = vecJRELocations.begin();
571 it != vecJRELocations.end(); it++)
573 jfw::CJavaInfo aInfo;
574 javaPluginError err = (*jfw_plugin_getJavaInfoByPathFunc)(
575 it->pData,
576 library.sVendor.pData,
577 versionInfo.sMinVersion.pData,
578 versionInfo.sMaxVersion.pData,
579 versionInfo.getExcludeVersions(),
580 versionInfo.getExcludeVersionSize(),
581 & aInfo.pInfo);
582 if (err == JFW_PLUGIN_E_NO_JRE)
583 continue;
584 if (err == JFW_PLUGIN_E_FAILED_VERSION)
585 continue;
586 else if (err !=JFW_PLUGIN_E_NONE)
587 return JFW_E_ERROR;
589 if (aInfo)
591 //We remember the very first installation in aCurrentInfo
592 if (aCurrentInfo.getLocation().getLength() == 0)
593 aCurrentInfo = aInfo;
594 // compare features
595 // If the user does not require any features (nFeatureFlags = 0)
596 // then the first installation is used
597 if ((aInfo.getFeatures() & nFeatureFlags) == nFeatureFlags)
599 //the just found Java implements all required features
600 //currently there is only accessibility!!!
601 aCurrentInfo = aInfo;
602 bInfoFound = true;
603 break;
606 }//end iterate over paths
607 if (bInfoFound == true)
608 break;
609 }// end iterate plug-ins
611 if ((JavaInfo*) aCurrentInfo)
613 jfw::NodeJava javaNode;
614 javaNode.setJavaInfo(aCurrentInfo,true);
615 javaNode.write();
617 if (pInfo !=NULL)
619 //copy to out param
620 *pInfo = aCurrentInfo.cloneJavaInfo();
621 //remember that this JRE was selected in this process
622 jfw::setJavaSelected();
625 else
627 errcode = JFW_E_NO_JAVA_FOUND;
630 catch (jfw::FrameworkException& e)
632 errcode = e.errorCode;
633 fprintf(stderr, "%s\n", e.message.getStr());
634 OSL_ENSURE(0, e.message.getStr());
637 return errcode;
639 sal_Bool SAL_CALL jfw_areEqualJavaInfo(
640 JavaInfo const * pInfoA,JavaInfo const * pInfoB)
642 if (pInfoA == pInfoB)
643 return sal_True;
644 if (pInfoA == NULL || pInfoB == NULL)
645 return sal_False;
646 rtl::OUString sVendor(pInfoA->sVendor);
647 rtl::OUString sLocation(pInfoA->sLocation);
648 rtl::OUString sVersion(pInfoA->sVersion);
649 rtl::ByteSequence sData(pInfoA->arVendorData);
650 if (sVendor.equals(pInfoB->sVendor) == sal_True
651 && sLocation.equals(pInfoB->sLocation) == sal_True
652 && sVersion.equals(pInfoB->sVersion) == sal_True
653 && pInfoA->nFeatures == pInfoB->nFeatures
654 && pInfoA->nRequirements == pInfoB->nRequirements
655 && sData == pInfoB->arVendorData)
657 return sal_True;
659 return sal_False;
663 void SAL_CALL jfw_freeJavaInfo(JavaInfo *pInfo)
665 if (pInfo == NULL)
666 return;
667 rtl_uString_release(pInfo->sVendor);
668 rtl_uString_release(pInfo->sLocation);
669 rtl_uString_release(pInfo->sVersion);
670 rtl_byte_sequence_release(pInfo->arVendorData);
671 rtl_freeMemory(pInfo);
674 javaFrameworkError SAL_CALL jfw_getSelectedJRE(JavaInfo **ppInfo)
676 javaFrameworkError errcode = JFW_E_NONE;
679 osl::MutexGuard guard(jfw::FwkMutex::get());
680 if (ppInfo == NULL)
681 return JFW_E_INVALID_ARG;
683 if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
685 rtl::OUString sJRE = jfw::BootParams::getJREHome();
687 jfw::CJavaInfo aInfo;
688 if ((errcode = jfw_getJavaInfoByPath(sJRE.pData, & aInfo.pInfo))
689 != JFW_E_NONE)
690 throw jfw::FrameworkException(
691 JFW_E_CONFIGURATION,
692 rtl::OString(
693 "[Java framework] The JRE specified by the bootstrap "
694 "variable UNO_JAVA_JFW_JREHOME or UNO_JAVA_JFW_ENV_JREHOME "
695 " could not be recognized. Check the values and make sure that you "
696 "use a plug-in library that can recognize that JRE."));
698 *ppInfo = aInfo.detach();
699 return JFW_E_NONE;
702 const jfw::MergedSettings settings;
703 jfw::CJavaInfo aInfo;
704 aInfo.attach(settings.createJavaInfo());
705 if (! aInfo)
707 *ppInfo = NULL;
708 return JFW_E_NONE;
710 //If the javavendors.xml has changed, then the current selected
711 //Java is not valid anymore
712 // /java/javaInfo/@vendorUpdate != javaSelection/updated (javavendors.xml)
713 rtl::OString sUpdated = jfw::getElementUpdated();
715 if (sUpdated.equals(settings.getJavaInfoAttrVendorUpdate()) == sal_False)
716 return JFW_E_INVALID_SETTINGS;
717 *ppInfo = aInfo.detach();
719 catch (jfw::FrameworkException& e)
721 errcode = e.errorCode;
722 fprintf(stderr, "%s\n", e.message.getStr());
723 OSL_ENSURE(0, e.message.getStr());
725 return errcode;
728 javaFrameworkError SAL_CALL jfw_isVMRunning(sal_Bool *bRunning)
730 osl::MutexGuard guard(jfw::FwkMutex::get());
731 if (bRunning == NULL)
732 return JFW_E_INVALID_ARG;
733 if (g_pJavaVM == NULL)
734 *bRunning = sal_False;
735 else
736 *bRunning = sal_True;
737 return JFW_E_NONE;
740 javaFrameworkError SAL_CALL jfw_getJavaInfoByPath(
741 rtl_uString *pPath, JavaInfo **ppInfo)
743 javaFrameworkError errcode = JFW_E_NONE;
746 osl::MutexGuard guard(jfw::FwkMutex::get());
747 if (pPath == NULL || ppInfo == NULL)
748 return JFW_E_INVALID_ARG;
750 jfw::VendorSettings aVendorSettings;
751 //Get a list of plugins which provide Java information
752 std::vector<jfw::PluginLibrary> vecPlugins =
753 aVendorSettings.getPluginData();
754 //Create a vector that holds the libraries, which will be later
755 //dynamically loaded;
756 boost::scoped_array<osl::Module> sarModules;
757 sarModules.reset(new osl::Module[vecPlugins.size()]);
758 osl::Module * arModules = sarModules.get();
760 typedef std::vector<rtl::OUString>::const_iterator CIT_VENDOR;
761 std::vector<rtl::OUString> vecVendors =
762 aVendorSettings.getSupportedVendors();
764 //Use every plug-in library to determine if the path represents a
765 //JRE. If a plugin recognized it then the loop will break
766 typedef std::vector<jfw::PluginLibrary>::const_iterator ci_pl;
767 int cModule = 0;
768 for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end();
769 i++, cModule++)
771 const jfw::PluginLibrary & library = *i;
772 jfw::VersionInfo versionInfo =
773 aVendorSettings.getVersionInformation(library.sVendor);
774 arModules[cModule].load(library.sPath);
775 osl::Module & pluginLib = arModules[cModule];
776 if (pluginLib.is() == sal_False)
778 rtl::OString msg = rtl::OUStringToOString(
779 library.sPath, osl_getThreadTextEncoding());
780 fprintf(stderr,"[jvmfwk] Could not load plugin %s\n" \
781 "Modify the javavendors.xml accordingly!\n", msg.getStr());
782 return JFW_E_NO_PLUGIN;
785 jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc =
786 (jfw_plugin_getJavaInfoByPath_ptr) pluginLib.getFunctionSymbol(
787 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getJavaInfoByPath")));
789 OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc);
790 if (jfw_plugin_getJavaInfoByPathFunc == NULL)
791 continue;
793 //ask the plugin if this is a JRE.
794 //If so check if it meets the version requirements.
795 //Only if it does return a JavaInfo
796 JavaInfo* pInfo = NULL;
797 javaPluginError plerr = (*jfw_plugin_getJavaInfoByPathFunc)(
798 pPath,
799 library.sVendor.pData,
800 versionInfo.sMinVersion.pData,
801 versionInfo.sMaxVersion.pData,
802 versionInfo.getExcludeVersions(),
803 versionInfo.getExcludeVersionSize(),
804 & pInfo);
806 if (plerr == JFW_PLUGIN_E_NONE)
808 //check if the vendor of the found JRE is supported
809 if (vecVendors.size() == 0)
811 //vendor does not matter
812 *ppInfo = pInfo;
813 break;
815 else
817 rtl::OUString sVendor(pInfo->sVendor);
818 CIT_VENDOR ivendor = std::find(vecVendors.begin(), vecVendors.end(),
819 sVendor);
820 if (ivendor != vecVendors.end())
822 *ppInfo = pInfo;
824 else
826 *ppInfo = NULL;
827 errcode = JFW_E_NOT_RECOGNIZED;
829 break;
832 else if(plerr == JFW_PLUGIN_E_FAILED_VERSION)
833 {//found JRE but it has the wrong version
834 *ppInfo = NULL;
835 errcode = JFW_E_FAILED_VERSION;
836 break;
838 else if (plerr == JFW_PLUGIN_E_NO_JRE)
839 {// plugin does not recognize this path as belonging to JRE
840 continue;
842 OSL_ASSERT(0);
844 if (*ppInfo == NULL && errcode != JFW_E_FAILED_VERSION)
845 errcode = JFW_E_NOT_RECOGNIZED;
847 catch (jfw::FrameworkException& e)
849 errcode = e.errorCode;
850 fprintf(stderr, "%s\n", e.message.getStr());
851 OSL_ENSURE(0, e.message.getStr());
854 return errcode;
858 javaFrameworkError SAL_CALL jfw_setSelectedJRE(JavaInfo const *pInfo)
860 javaFrameworkError errcode = JFW_E_NONE;
863 osl::MutexGuard guard(jfw::FwkMutex::get());
864 if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
865 return JFW_E_DIRECT_MODE;
866 //check if pInfo is the selected JRE
867 JavaInfo *currentInfo = NULL;
868 errcode = jfw_getSelectedJRE( & currentInfo);
869 if (errcode != JFW_E_NONE && errcode != JFW_E_INVALID_SETTINGS)
870 return errcode;
872 if (jfw_areEqualJavaInfo(currentInfo, pInfo) == sal_False)
874 jfw::NodeJava node;
875 node.setJavaInfo(pInfo, false);
876 node.write();
877 //remember that the JRE was selected in this process
878 jfw::setJavaSelected();
881 catch (jfw::FrameworkException& e)
883 errcode = e.errorCode;
884 fprintf(stderr, "%s\n", e.message.getStr());
885 OSL_ENSURE(0, e.message.getStr());
887 return errcode;
889 javaFrameworkError SAL_CALL jfw_setEnabled(sal_Bool bEnabled)
891 javaFrameworkError errcode = JFW_E_NONE;
894 osl::MutexGuard guard(jfw::FwkMutex::get());
895 if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
896 return JFW_E_DIRECT_MODE;
898 if (g_bEnabledSwitchedOn == false && bEnabled == sal_True)
900 //When the process started then Enabled was false.
901 //This is first time enabled is set to true.
902 //That means, no preparational work has been done, such as setting the
903 //LD_LIBRARY_PATH, etc.
905 //check if Enabled is false;
906 const jfw::MergedSettings settings;
907 if (settings.getEnabled() == sal_False)
908 g_bEnabledSwitchedOn = true;
910 jfw::NodeJava node;
911 node.setEnabled(bEnabled);
912 node.write();
914 catch (jfw::FrameworkException& e)
916 errcode = e.errorCode;
917 fprintf(stderr, "%s\n", e.message.getStr());
918 OSL_ENSURE(0, e.message.getStr());
920 return errcode;
923 javaFrameworkError SAL_CALL jfw_getEnabled(sal_Bool *pbEnabled)
925 javaFrameworkError errcode = JFW_E_NONE;
928 if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
929 return JFW_E_DIRECT_MODE;
930 osl::MutexGuard guard(jfw::FwkMutex::get());
931 if (pbEnabled == NULL)
932 return JFW_E_INVALID_ARG;
933 jfw::MergedSettings settings;
934 *pbEnabled = settings.getEnabled();
936 catch (jfw::FrameworkException& e)
938 errcode = e.errorCode;
939 fprintf(stderr, "%s\n", e.message.getStr());
940 OSL_ENSURE(0, e.message.getStr());
942 return errcode;
946 javaFrameworkError SAL_CALL jfw_setVMParameters(
947 rtl_uString * * arOptions, sal_Int32 nLen)
949 javaFrameworkError errcode = JFW_E_NONE;
952 osl::MutexGuard guard(jfw::FwkMutex::get());
953 if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
954 return JFW_E_DIRECT_MODE;
955 jfw::NodeJava node;
956 if (arOptions == NULL && nLen != 0)
957 return JFW_E_INVALID_ARG;
958 node.setVmParameters(arOptions, nLen);
959 node.write();
961 catch (jfw::FrameworkException& e)
963 errcode = e.errorCode;
964 fprintf(stderr, "%s\n", e.message.getStr());
965 OSL_ENSURE(0, e.message.getStr());
968 return errcode;
971 javaFrameworkError SAL_CALL jfw_getVMParameters(
972 rtl_uString *** parOptions, sal_Int32 * pLen)
974 javaFrameworkError errcode = JFW_E_NONE;
977 osl::MutexGuard guard(jfw::FwkMutex::get());
978 if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
979 return JFW_E_DIRECT_MODE;
981 if (parOptions == NULL || pLen == NULL)
982 return JFW_E_INVALID_ARG;
983 const jfw::MergedSettings settings;
984 settings.getVmParametersArray(parOptions, pLen);
986 catch (jfw::FrameworkException& e)
988 errcode = e.errorCode;
989 fprintf(stderr, "%s\n", e.message.getStr());
990 OSL_ENSURE(0, e.message.getStr());
992 return errcode;
995 javaFrameworkError SAL_CALL jfw_setUserClassPath(rtl_uString * pCp)
997 javaFrameworkError errcode = JFW_E_NONE;
1000 osl::MutexGuard guard(jfw::FwkMutex::get());
1001 if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
1002 return JFW_E_DIRECT_MODE;
1003 jfw::NodeJava node;
1004 if (pCp == NULL)
1005 return JFW_E_INVALID_ARG;
1006 node.setUserClassPath(pCp);
1007 node.write();
1009 catch (jfw::FrameworkException& e)
1011 errcode = e.errorCode;
1012 fprintf(stderr, "%s\n", e.message.getStr());
1013 OSL_ENSURE(0, e.message.getStr());
1015 return errcode;
1018 javaFrameworkError SAL_CALL jfw_getUserClassPath(rtl_uString ** ppCP)
1020 javaFrameworkError errcode = JFW_E_NONE;
1023 osl::MutexGuard guard(jfw::FwkMutex::get());
1024 if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
1025 return JFW_E_DIRECT_MODE;
1026 if (ppCP == NULL)
1027 return JFW_E_INVALID_ARG;
1028 const jfw::MergedSettings settings;
1029 *ppCP = settings.getUserClassPath().pData;
1030 rtl_uString_acquire(*ppCP);
1032 catch (jfw::FrameworkException& e)
1034 errcode = e.errorCode;
1035 fprintf(stderr, "%s\n", e.message.getStr());
1036 OSL_ENSURE(0, e.message.getStr());
1038 return errcode;
1041 javaFrameworkError SAL_CALL jfw_addJRELocation(rtl_uString * sLocation)
1043 javaFrameworkError errcode = JFW_E_NONE;
1046 osl::MutexGuard guard(jfw::FwkMutex::get());
1047 if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
1048 return JFW_E_DIRECT_MODE;
1049 jfw::NodeJava node;
1050 if (sLocation == NULL)
1051 return JFW_E_INVALID_ARG;
1052 node.load();
1053 node.addJRELocation(sLocation);
1054 node.write();
1056 catch (jfw::FrameworkException& e)
1058 errcode = e.errorCode;
1059 fprintf(stderr, "%s\n", e.message.getStr());
1060 OSL_ENSURE(0, e.message.getStr());
1063 return errcode;
1067 javaFrameworkError SAL_CALL jfw_setJRELocations(
1068 rtl_uString ** arLocations, sal_Int32 nLen)
1070 javaFrameworkError errcode = JFW_E_NONE;
1073 osl::MutexGuard guard(jfw::FwkMutex::get());
1074 if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
1075 return JFW_E_DIRECT_MODE;
1076 jfw::NodeJava node;
1077 if (arLocations == NULL && nLen != 0)
1078 return JFW_E_INVALID_ARG;
1079 node.setJRELocations(arLocations, nLen);
1080 node.write();
1082 catch (jfw::FrameworkException& e)
1084 errcode = e.errorCode;
1085 fprintf(stderr, "%s\n", e.message.getStr());
1086 OSL_ENSURE(0, e.message.getStr());
1088 return errcode;
1092 javaFrameworkError SAL_CALL jfw_getJRELocations(
1093 rtl_uString *** parLocations, sal_Int32 *pLen)
1095 javaFrameworkError errcode = JFW_E_NONE;
1098 osl::MutexGuard guard(jfw::FwkMutex::get());
1099 if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
1100 return JFW_E_DIRECT_MODE;
1102 if (parLocations == NULL || pLen == NULL)
1103 return JFW_E_INVALID_ARG;
1104 const jfw::MergedSettings settings;
1105 settings.getJRELocations(parLocations, pLen);
1107 catch (jfw::FrameworkException& e)
1109 errcode = e.errorCode;
1110 fprintf(stderr, "%s\n", e.message.getStr());
1111 OSL_ENSURE(0, e.message.getStr());
1114 return errcode;
1118 javaFrameworkError jfw_existJRE(const JavaInfo *pInfo, sal_Bool *exist)
1120 javaFrameworkError ret = JFW_E_NONE;
1121 if (!pInfo || !exist)
1122 return JFW_E_INVALID_ARG;
1123 ::rtl::OUString sLocation(pInfo->sLocation);
1125 if (sLocation.getLength() == 0)
1126 return JFW_E_INVALID_ARG;
1128 ::osl::DirectoryItem item;
1129 ::osl::File::RC rc_item = ::osl::DirectoryItem::get(sLocation, item);
1130 if (::osl::File::E_None == rc_item)
1132 *exist = sal_True;
1134 else if (::osl::File::E_NOENT == rc_item)
1136 *exist = sal_False;
1138 else
1140 ret = JFW_E_ERROR;
1143 return ret;
1146 void SAL_CALL jfw_lock()
1148 jfw::FwkMutex::get().acquire();
1151 void SAL_CALL jfw_unlock()
1153 jfw::FwkMutex::get().release();
1157 namespace jfw
1159 CJavaInfo::CJavaInfo(): pInfo(0)
1163 CJavaInfo::CJavaInfo(const CJavaInfo & info)
1165 pInfo = copyJavaInfo(info.pInfo);
1168 CJavaInfo::CJavaInfo(::JavaInfo * info, _transfer_ownership)
1170 pInfo = info;
1172 CJavaInfo CJavaInfo::createWrapper(::JavaInfo* info)
1174 return CJavaInfo(info, TRANSFER);
1176 void CJavaInfo::attach(::JavaInfo * info)
1178 jfw_freeJavaInfo(pInfo);
1179 pInfo = info;
1181 ::JavaInfo * CJavaInfo::detach()
1183 JavaInfo * tmp = pInfo;
1184 pInfo = NULL;
1185 return tmp;
1188 CJavaInfo::~CJavaInfo()
1190 jfw_freeJavaInfo(pInfo);
1193 CJavaInfo::operator ::JavaInfo* ()
1195 return pInfo;
1198 JavaInfo * CJavaInfo::copyJavaInfo(const JavaInfo * pInfo)
1200 if (pInfo == NULL)
1201 return NULL;
1202 JavaInfo* newInfo =
1203 (JavaInfo*) rtl_allocateMemory(sizeof(JavaInfo));
1204 if (newInfo)
1206 rtl_copyMemory(newInfo, pInfo, sizeof(JavaInfo));
1207 rtl_uString_acquire(pInfo->sVendor);
1208 rtl_uString_acquire(pInfo->sLocation);
1209 rtl_uString_acquire(pInfo->sVersion);
1210 rtl_byte_sequence_acquire(pInfo->arVendorData);
1212 return newInfo;
1216 JavaInfo* CJavaInfo::cloneJavaInfo() const
1218 if (pInfo == NULL)
1219 return NULL;
1220 return copyJavaInfo(pInfo);
1223 CJavaInfo & CJavaInfo::operator = (const CJavaInfo& info)
1225 if (&info == this)
1226 return *this;
1228 jfw_freeJavaInfo(pInfo);
1229 pInfo = copyJavaInfo(info.pInfo);
1230 return *this;
1232 CJavaInfo & CJavaInfo::operator = (const ::JavaInfo* info)
1234 if (info == pInfo)
1235 return *this;
1237 jfw_freeJavaInfo(pInfo);
1238 pInfo = copyJavaInfo(info);
1239 return *this;
1242 const ::JavaInfo* CJavaInfo::operator ->() const
1244 return pInfo;
1247 CJavaInfo::operator JavaInfo const * () const
1249 return pInfo;
1251 // ::JavaInfo** CJavaInfo::operator & ()
1252 // {
1253 // return & pInfo;
1254 // }
1256 rtl::OUString CJavaInfo::getVendor() const
1258 if (pInfo)
1259 return rtl::OUString(pInfo->sVendor);
1260 else
1261 return rtl::OUString();
1264 rtl::OUString CJavaInfo::getLocation() const
1266 if (pInfo)
1267 return rtl::OUString(pInfo->sLocation);
1268 else
1269 return rtl::OUString();
1272 sal_uInt64 CJavaInfo::getFeatures() const
1274 if (pInfo)
1275 return pInfo->nFeatures;
1276 else
1277 return 0l;