1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <rtl/ustring.hxx>
21 #include <rtl/ustrbuf.hxx>
22 #include <sal/log.hxx>
23 #include <libxml/xpathInternals.h>
24 #include <osl/file.hxx>
25 #include <osl/thread.hxx>
26 #include <o3tl/string_view.hxx>
27 #include "framework.hxx"
28 #include <fwkutil.hxx>
29 #include <elements.hxx>
30 #include <fwkbase.hxx>
35 #define UNO_JAVA_JFW_PARAMETER "UNO_JAVA_JFW_PARAMETER_"
36 #define UNO_JAVA_JFW_JREHOME "UNO_JAVA_JFW_JREHOME"
37 #define UNO_JAVA_JFW_ENV_JREHOME "UNO_JAVA_JFW_ENV_JREHOME"
38 #define UNO_JAVA_JFW_CLASSPATH "UNO_JAVA_JFW_CLASSPATH"
39 #define UNO_JAVA_JFW_ENV_CLASSPATH "UNO_JAVA_JFW_ENV_CLASSPATH"
40 #define UNO_JAVA_JFW_CLASSPATH_URLS "UNO_JAVA_JFW_CLASSPATH_URLS"
41 #define UNO_JAVA_JFW_VENDOR_SETTINGS "UNO_JAVA_JFW_VENDOR_SETTINGS"
45 static bool g_bJavaSet
= false;
50 // The paths are used in libxml. On Windows, it takes UTF-8 paths.
51 constexpr rtl_TextEncoding
PathEncoding() { return RTL_TEXTENCODING_UTF8
; }
53 rtl_TextEncoding
PathEncoding() { return osl_getThreadTextEncoding(); }
56 OString
getVendorSettingsPath(OUString
const & sURL
)
60 OUString sSystemPathSettings
;
61 if (osl_getSystemPathFromFileURL(sURL
.pData
,
62 & sSystemPathSettings
.pData
) != osl_File_E_None
)
63 throw FrameworkException(
65 "[Java framework] Error in function getVendorSettingsPath (fwkbase.cxx) ");
66 OString osSystemPathSettings
= OUStringToOString(sSystemPathSettings
, PathEncoding());
67 return osSystemPathSettings
;
70 OUString
getParam(OUString
const & name
)
73 bool b
= Bootstrap()->getFrom(name
, retVal
);
76 "Using bootstrap parameter " << name
<< " = \"" << retVal
<< "\""
77 << (b
? "" : " (undefined)"));
81 OUString
getParamFirstUrl(OUString
const & name
)
83 // Some parameters can consist of multiple URLs (separated by space
84 // characters, although trim() harmlessly also removes other white-space),
85 // of which only the first is used:
86 return getParam(name
).trim().getToken(0, ' ');
92 VendorSettings::VendorSettings()
94 OUString
xmlDocVendorSettingsFileUrl(BootParams::getVendorSettings());
95 //Prepare the xml document and context
96 OString sSettingsPath
= getVendorSettingsPath(xmlDocVendorSettingsFileUrl
);
97 if (sSettingsPath
.isEmpty())
99 OString
sMsg("[Java framework] A vendor settings file was not specified."
100 "Check the bootstrap parameter " UNO_JAVA_JFW_VENDOR_SETTINGS
".");
101 SAL_WARN( "jfw", sMsg
);
102 throw FrameworkException(JFW_E_CONFIGURATION
, sMsg
);
104 if (sSettingsPath
.isEmpty())
107 m_xmlDocVendorSettings
= xmlParseFile(sSettingsPath
.getStr());
108 if (m_xmlDocVendorSettings
== nullptr)
109 throw FrameworkException(
111 OString::Concat("[Java framework] Error while parsing file: ")
112 + sSettingsPath
+ ".");
114 m_xmlPathContextVendorSettings
= xmlXPathNewContext(m_xmlDocVendorSettings
);
115 int res
= xmlXPathRegisterNs(
116 m_xmlPathContextVendorSettings
, reinterpret_cast<xmlChar
const *>("jf"),
117 reinterpret_cast<xmlChar
const *>(NS_JAVA_FRAMEWORK
));
119 throw FrameworkException(JFW_E_ERROR
,
120 "[Java framework] Error in constructor VendorSettings::VendorSettings() (fwkbase.cxx)");
123 VersionInfo
VendorSettings::getVersionInformation(std::u16string_view sVendor
) const
125 OSL_ASSERT(!sVendor
.empty());
126 OString osVendor
= OUStringToOString(sVendor
, RTL_TEXTENCODING_UTF8
);
127 CXPathObjectPtr pathObject
= xmlXPathEvalExpression(
128 reinterpret_cast<xmlChar
const *>(
130 "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"" + osVendor
131 + "\"]/jf:minVersion").getStr()),
132 m_xmlPathContextVendorSettings
);
133 if (xmlXPathNodeSetIsEmpty(pathObject
->nodesetval
))
137 #if defined MACOSX && defined __aarch64__
145 VersionInfo aVersionInfo
;
147 OString sExpression
=
148 "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"" +
149 osVendor
+ "\"]/jf:minVersion";
151 CXPathObjectPtr xPathObjectMin
=
152 xmlXPathEvalExpression(reinterpret_cast<xmlChar
const *>(sExpression
.getStr()),
153 m_xmlPathContextVendorSettings
);
154 if (xmlXPathNodeSetIsEmpty(xPathObjectMin
->nodesetval
))
156 aVersionInfo
.sMinVersion
.clear();
160 CXmlCharPtr sVersion
= xmlNodeListGetString(
161 m_xmlDocVendorSettings
,
162 xPathObjectMin
->nodesetval
->nodeTab
[0]->xmlChildrenNode
, 1);
163 OString
osVersion(sVersion
);
164 aVersionInfo
.sMinVersion
= OStringToOUString(
165 osVersion
, RTL_TEXTENCODING_UTF8
);
169 sExpression
= "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"" +
170 osVendor
+ "\"]/jf:maxVersion";
171 CXPathObjectPtr xPathObjectMax
= xmlXPathEvalExpression(
172 reinterpret_cast<xmlChar
const *>(sExpression
.getStr()),
173 m_xmlPathContextVendorSettings
);
174 if (xmlXPathNodeSetIsEmpty(xPathObjectMax
->nodesetval
))
176 aVersionInfo
.sMaxVersion
.clear();
180 CXmlCharPtr sVersion
= xmlNodeListGetString(
181 m_xmlDocVendorSettings
,
182 xPathObjectMax
->nodesetval
->nodeTab
[0]->xmlChildrenNode
, 1);
183 OString
osVersion(sVersion
);
184 aVersionInfo
.sMaxVersion
= OStringToOUString(
185 osVersion
, RTL_TEXTENCODING_UTF8
);
188 //Get excludeVersions
189 sExpression
= "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"" +
190 osVendor
+ "\"]/jf:excludeVersions/jf:version";
191 CXPathObjectPtr xPathObjectVersions
=
192 xmlXPathEvalExpression(reinterpret_cast<xmlChar
const *>(sExpression
.getStr()),
193 m_xmlPathContextVendorSettings
);
194 if (!xmlXPathNodeSetIsEmpty(xPathObjectVersions
->nodesetval
))
196 xmlNode
* cur
= xPathObjectVersions
->nodesetval
->nodeTab
[0];
197 while (cur
!= nullptr)
199 if (cur
->type
== XML_ELEMENT_NODE
)
201 if (xmlStrcmp(cur
->name
, reinterpret_cast<xmlChar
const *>("version")) == 0)
203 CXmlCharPtr sVersion
= xmlNodeListGetString(
204 m_xmlDocVendorSettings
, cur
->xmlChildrenNode
, 1);
205 OString
osVersion(sVersion
);
206 OUString usVersion
= OStringToOUString(
207 osVersion
, RTL_TEXTENCODING_UTF8
);
208 aVersionInfo
.vecExcludeVersions
.push_back(usVersion
);
217 ::std::vector
<OString
> BootParams::getVMParameters()
219 ::std::vector
<OString
> vecParams
;
221 for (sal_Int32 i
= 1; ; i
++)
223 OUString sName
= UNO_JAVA_JFW_PARAMETER
+ OUString::number(i
);
225 if (Bootstrap()->getFrom(sName
, sValue
))
228 OUStringToOString(sValue
, osl_getThreadTextEncoding());
229 vecParams
.push_back(sParam
);
232 "Using bootstrap parameter " << sName
<< " = " << sParam
);
240 OUString
BootParams::getUserData()
242 return getParamFirstUrl("UNO_JAVA_JFW_USER_DATA");
245 OUString
BootParams::getSharedData()
247 return getParamFirstUrl("UNO_JAVA_JFW_SHARED_DATA");
250 OString
BootParams::getClasspath()
254 if (Bootstrap()->getFrom( UNO_JAVA_JFW_CLASSPATH
, sCP
))
256 sClassPath
= OUStringToOString(sCP
, PathEncoding());
259 "Using bootstrap parameter " UNO_JAVA_JFW_CLASSPATH
" = "
264 if (Bootstrap()->getFrom( UNO_JAVA_JFW_ENV_CLASSPATH
, sEnvCP
))
266 char * pCp
= getenv("CLASSPATH");
269 sClassPath
+= OStringChar(SAL_PATHSEPARATOR
) + pCp
;
273 "Using bootstrap parameter " UNO_JAVA_JFW_ENV_CLASSPATH
274 " and class path is: " << (pCp
? pCp
: ""));
280 OUString
BootParams::getVendorSettings()
283 if (Bootstrap()->getFrom(UNO_JAVA_JFW_VENDOR_SETTINGS
, sVendor
))
285 //check the value of the bootstrap variable
286 jfw::FileStatus s
= checkFileURL(sVendor
);
289 //This bootstrap parameter can contain a relative URL
290 OUString sAbsoluteUrl
;
291 OUString sBaseDir
= getLibraryLocation();
292 if (File::getAbsoluteFileURL(sBaseDir
, sVendor
, sAbsoluteUrl
)
294 throw FrameworkException(
296 "[Java framework] Invalid value for bootstrap variable: "
297 UNO_JAVA_JFW_VENDOR_SETTINGS
);
298 sVendor
= sAbsoluteUrl
;
299 s
= checkFileURL(sVendor
);
300 if (s
== jfw::FILE_INVALID
|| s
== jfw::FILE_DOES_NOT_EXIST
)
302 throw FrameworkException(
304 "[Java framework] Invalid value for bootstrap variable: "
305 UNO_JAVA_JFW_VENDOR_SETTINGS
);
310 "Using bootstrap parameter " UNO_JAVA_JFW_VENDOR_SETTINGS
" = "
316 OUString
BootParams::getJREHome()
320 bool bJRE
= Bootstrap()->getFrom(UNO_JAVA_JFW_JREHOME
, sJRE
);
321 bool bEnvJRE
= Bootstrap()->getFrom(UNO_JAVA_JFW_ENV_JREHOME
, sEnvJRE
);
325 throw FrameworkException(
327 "[Java framework] Both bootstrap parameter "
328 UNO_JAVA_JFW_JREHOME
" and "
329 UNO_JAVA_JFW_ENV_JREHOME
" are set. However only one of them can be set."
330 "Check bootstrap parameters: environment variables, command line "
331 "arguments, rc/ini files for executable and java framework library.");
335 const char * pJRE
= getenv("JAVA_HOME");
338 throw FrameworkException(
340 "[Java framework] Both bootstrap parameter "
341 UNO_JAVA_JFW_ENV_JREHOME
" is set, but the environment variable "
342 "JAVA_HOME is not set.");
345 OUString usJRE
= OStringToOUString(osJRE
, osl_getThreadTextEncoding());
346 if (File::getFileURLFromSystemPath(usJRE
, sJRE
) != File::E_None
)
347 throw FrameworkException(
349 "[Java framework] Error in function BootParams::getJREHome() "
353 "Using bootstrap parameter " UNO_JAVA_JFW_ENV_JREHOME
354 " with JAVA_HOME = " << pJRE
);
356 else if (getMode() == JFW_MODE_DIRECT
&& !bJRE
)
358 throw FrameworkException(
360 "[Java framework] The bootstrap parameter "
361 UNO_JAVA_JFW_ENV_JREHOME
" or " UNO_JAVA_JFW_JREHOME
362 " must be set in direct mode.");
367 "Using bootstrap parameter " UNO_JAVA_JFW_JREHOME
" = " << sJRE
);
371 OUString
BootParams::getClasspathUrls()
374 Bootstrap()->getFrom( UNO_JAVA_JFW_CLASSPATH_URLS
, sParams
);
377 "Using bootstrap parameter " UNO_JAVA_JFW_CLASSPATH_URLS
" = "
384 static bool g_bMode
= false;
385 static JFW_MODE g_mode
= JFW_MODE_APPLICATION
;
389 //check if either of the "direct mode" bootstrap variables is set
390 bool bDirectMode
= true;
392 const rtl::Bootstrap
* aBoot
= Bootstrap();
393 if (!aBoot
->getFrom(UNO_JAVA_JFW_JREHOME
, sValue
))
395 if (!aBoot
->getFrom(UNO_JAVA_JFW_ENV_JREHOME
, sValue
))
397 if (!aBoot
->getFrom(UNO_JAVA_JFW_CLASSPATH
, sValue
))
399 if (!aBoot
->getFrom(UNO_JAVA_JFW_ENV_CLASSPATH
, sValue
))
401 OUString sParams
= UNO_JAVA_JFW_PARAMETER
+
403 if (!aBoot
->getFrom(sParams
, sValue
))
413 g_mode
= JFW_MODE_DIRECT
;
415 g_mode
= JFW_MODE_APPLICATION
;
422 OUString
getApplicationClassPath()
424 OSL_ASSERT(getMode() == JFW_MODE_APPLICATION
);
425 OUString sParams
= BootParams::getClasspathUrls();
426 if (sParams
.isEmpty())
433 OUString
token( o3tl::trim(o3tl::getToken(sParams
, 0, ' ', index
)) );
434 if (!token
.isEmpty())
436 OUString systemPathElement
;
437 oslFileError rc
= osl_getSystemPathFromFileURL(
438 token
.pData
, &systemPathElement
.pData
);
439 OSL_ASSERT( rc
== osl_File_E_None
);
440 if (rc
== osl_File_E_None
&& !systemPathElement
.isEmpty())
442 if (buf
.getLength() > 0)
443 buf
.append( SAL_PATHSEPARATOR
);
444 buf
.append( systemPathElement
);
449 return buf
.makeStringAndClear();
452 OString
makeClassPathOption(std::u16string_view sUserClassPath
)
454 //Compose the class path
456 OUStringBuffer
sBufCP(4096);
458 // append all user selected jars to the class path
459 if (!sUserClassPath
.empty())
460 sBufCP
.append(sUserClassPath
);
462 //append all jar libraries and components to the class path
463 OUString sAppCP
= getApplicationClassPath();
464 if (!sAppCP
.isEmpty())
466 if (!sUserClassPath
.empty())
468 sBufCP
.append(SAL_PATHSEPARATOR
);
470 sBufCP
.append(sAppCP
);
473 sPaths
= OUStringToOString(sBufCP
.makeStringAndClear(), PathEncoding());
474 if (sPaths
.isEmpty()) {
478 OString sOptionClassPath
= "-Djava.class.path=" + sPaths
;
479 return sOptionClassPath
;
482 OString
getUserSettingsPath()
484 return getSettingsPath(BootParams::getUserData());
487 OString
getSharedSettingsPath()
489 return getSettingsPath(BootParams::getSharedData());
492 OString
getSettingsPath( const OUString
& sURL
)
497 if (osl_getSystemPathFromFileURL(sURL
.pData
,
498 & sPath
.pData
) != osl_File_E_None
)
499 throw FrameworkException(
501 "[Java framework] Error in function ::getSettingsPath (fwkbase.cxx).");
502 return OUStringToOString(sPath
, PathEncoding());
505 OString
getVendorSettingsPath()
507 return getVendorSettingsPath(BootParams::getVendorSettings());
510 void setJavaSelected()
515 bool wasJavaSelectedInSameProcess()
517 //g_setJavaProcId not set means no Java selected
524 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */