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 "framework.hxx"
27 #include <fwkutil.hxx>
28 #include <elements.hxx>
29 #include <fwkbase.hxx>
34 #define UNO_JAVA_JFW_PARAMETER "UNO_JAVA_JFW_PARAMETER_"
35 #define UNO_JAVA_JFW_JREHOME "UNO_JAVA_JFW_JREHOME"
36 #define UNO_JAVA_JFW_ENV_JREHOME "UNO_JAVA_JFW_ENV_JREHOME"
37 #define UNO_JAVA_JFW_CLASSPATH "UNO_JAVA_JFW_CLASSPATH"
38 #define UNO_JAVA_JFW_ENV_CLASSPATH "UNO_JAVA_JFW_ENV_CLASSPATH"
39 #define UNO_JAVA_JFW_CLASSPATH_URLS "UNO_JAVA_JFW_CLASSPATH_URLS"
40 #define UNO_JAVA_JFW_VENDOR_SETTINGS "UNO_JAVA_JFW_VENDOR_SETTINGS"
44 static bool g_bJavaSet
= false;
49 // The paths are used in libxml. On Windows, it takes UTF-8 paths.
50 constexpr rtl_TextEncoding
PathEncoding() { return RTL_TEXTENCODING_UTF8
; }
52 rtl_TextEncoding
PathEncoding() { return osl_getThreadTextEncoding(); }
55 OString
getVendorSettingsPath(OUString
const & sURL
)
59 OUString sSystemPathSettings
;
60 if (osl_getSystemPathFromFileURL(sURL
.pData
,
61 & sSystemPathSettings
.pData
) != osl_File_E_None
)
62 throw FrameworkException(
64 "[Java framework] Error in function getVendorSettingsPath (fwkbase.cxx) ");
65 OString osSystemPathSettings
= OUStringToOString(sSystemPathSettings
, PathEncoding());
66 return osSystemPathSettings
;
69 OUString
getParam(OUString
const & name
)
72 bool b
= Bootstrap()->getFrom(name
, retVal
);
75 "Using bootstrap parameter " << name
<< " = \"" << retVal
<< "\""
76 << (b
? "" : " (undefined)"));
80 OUString
getParamFirstUrl(OUString
const & name
)
82 // Some parameters can consist of multiple URLs (separated by space
83 // characters, although trim() harmlessly also removes other white-space),
84 // of which only the first is used:
85 return getParam(name
).trim().getToken(0, ' ');
91 VendorSettings::VendorSettings()
93 OUString
xmlDocVendorSettingsFileUrl(BootParams::getVendorSettings());
94 //Prepare the xml document and context
95 OString sSettingsPath
= getVendorSettingsPath(xmlDocVendorSettingsFileUrl
);
96 if (sSettingsPath
.isEmpty())
98 OString
sMsg("[Java framework] A vendor settings file was not specified."
99 "Check the bootstrap parameter " UNO_JAVA_JFW_VENDOR_SETTINGS
".");
100 SAL_WARN( "jfw", sMsg
);
101 throw FrameworkException(JFW_E_CONFIGURATION
, sMsg
);
103 if (sSettingsPath
.isEmpty())
106 m_xmlDocVendorSettings
= xmlParseFile(sSettingsPath
.getStr());
107 if (m_xmlDocVendorSettings
== nullptr)
108 throw FrameworkException(
110 OString::Concat("[Java framework] Error while parsing file: ")
111 + sSettingsPath
+ ".");
113 m_xmlPathContextVendorSettings
= xmlXPathNewContext(m_xmlDocVendorSettings
);
114 int res
= xmlXPathRegisterNs(
115 m_xmlPathContextVendorSettings
, reinterpret_cast<xmlChar
const *>("jf"),
116 reinterpret_cast<xmlChar
const *>(NS_JAVA_FRAMEWORK
));
118 throw FrameworkException(JFW_E_ERROR
,
119 "[Java framework] Error in constructor VendorSettings::VendorSettings() (fwkbase.cxx)");
122 VersionInfo
VendorSettings::getVersionInformation(std::u16string_view sVendor
) const
124 OSL_ASSERT(!sVendor
.empty());
125 OString osVendor
= OUStringToOString(sVendor
, RTL_TEXTENCODING_UTF8
);
126 CXPathObjectPtr pathObject
= xmlXPathEvalExpression(
127 reinterpret_cast<xmlChar
const *>(
129 "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"" + osVendor
130 + "\"]/jf:minVersion").getStr()),
131 m_xmlPathContextVendorSettings
);
132 if (xmlXPathNodeSetIsEmpty(pathObject
->nodesetval
))
136 #if defined MACOSX && defined __aarch64__
144 VersionInfo aVersionInfo
;
146 OString sExpression
=
147 "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"" +
148 osVendor
+ "\"]/jf:minVersion";
150 CXPathObjectPtr xPathObjectMin
=
151 xmlXPathEvalExpression(reinterpret_cast<xmlChar
const *>(sExpression
.getStr()),
152 m_xmlPathContextVendorSettings
);
153 if (xmlXPathNodeSetIsEmpty(xPathObjectMin
->nodesetval
))
155 aVersionInfo
.sMinVersion
.clear();
159 CXmlCharPtr sVersion
= xmlNodeListGetString(
160 m_xmlDocVendorSettings
,
161 xPathObjectMin
->nodesetval
->nodeTab
[0]->xmlChildrenNode
, 1);
162 OString
osVersion(sVersion
);
163 aVersionInfo
.sMinVersion
= OStringToOUString(
164 osVersion
, RTL_TEXTENCODING_UTF8
);
168 sExpression
= "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"" +
169 osVendor
+ "\"]/jf:maxVersion";
170 CXPathObjectPtr xPathObjectMax
= xmlXPathEvalExpression(
171 reinterpret_cast<xmlChar
const *>(sExpression
.getStr()),
172 m_xmlPathContextVendorSettings
);
173 if (xmlXPathNodeSetIsEmpty(xPathObjectMax
->nodesetval
))
175 aVersionInfo
.sMaxVersion
.clear();
179 CXmlCharPtr sVersion
= xmlNodeListGetString(
180 m_xmlDocVendorSettings
,
181 xPathObjectMax
->nodesetval
->nodeTab
[0]->xmlChildrenNode
, 1);
182 OString
osVersion(sVersion
);
183 aVersionInfo
.sMaxVersion
= OStringToOUString(
184 osVersion
, RTL_TEXTENCODING_UTF8
);
187 //Get excludeVersions
188 sExpression
= "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"" +
189 osVendor
+ "\"]/jf:excludeVersions/jf:version";
190 CXPathObjectPtr xPathObjectVersions
=
191 xmlXPathEvalExpression(reinterpret_cast<xmlChar
const *>(sExpression
.getStr()),
192 m_xmlPathContextVendorSettings
);
193 if (!xmlXPathNodeSetIsEmpty(xPathObjectVersions
->nodesetval
))
195 xmlNode
* cur
= xPathObjectVersions
->nodesetval
->nodeTab
[0];
196 while (cur
!= nullptr)
198 if (cur
->type
== XML_ELEMENT_NODE
)
200 if (xmlStrcmp(cur
->name
, reinterpret_cast<xmlChar
const *>("version")) == 0)
202 CXmlCharPtr sVersion
= xmlNodeListGetString(
203 m_xmlDocVendorSettings
, cur
->xmlChildrenNode
, 1);
204 OString
osVersion(sVersion
);
205 OUString usVersion
= OStringToOUString(
206 osVersion
, RTL_TEXTENCODING_UTF8
);
207 aVersionInfo
.vecExcludeVersions
.push_back(usVersion
);
216 ::std::vector
<OString
> BootParams::getVMParameters()
218 ::std::vector
<OString
> vecParams
;
220 for (sal_Int32 i
= 1; ; i
++)
222 OUString sName
= UNO_JAVA_JFW_PARAMETER
+ OUString::number(i
);
224 if (Bootstrap()->getFrom(sName
, sValue
))
227 OUStringToOString(sValue
, osl_getThreadTextEncoding());
228 vecParams
.push_back(sParam
);
231 "Using bootstrap parameter " << sName
<< " = " << sParam
);
239 OUString
BootParams::getUserData()
241 return getParamFirstUrl("UNO_JAVA_JFW_USER_DATA");
244 OUString
BootParams::getSharedData()
246 return getParamFirstUrl("UNO_JAVA_JFW_SHARED_DATA");
249 OString
BootParams::getClasspath()
253 if (Bootstrap()->getFrom( UNO_JAVA_JFW_CLASSPATH
, sCP
))
255 sClassPath
= OUStringToOString(sCP
, PathEncoding());
258 "Using bootstrap parameter " UNO_JAVA_JFW_CLASSPATH
" = "
263 if (Bootstrap()->getFrom( UNO_JAVA_JFW_ENV_CLASSPATH
, sEnvCP
))
265 char * pCp
= getenv("CLASSPATH");
268 sClassPath
+= OStringChar(SAL_PATHSEPARATOR
) + pCp
;
272 "Using bootstrap parameter " UNO_JAVA_JFW_ENV_CLASSPATH
273 " and class path is: " << (pCp
? pCp
: ""));
279 OUString
BootParams::getVendorSettings()
282 if (Bootstrap()->getFrom(UNO_JAVA_JFW_VENDOR_SETTINGS
, sVendor
))
284 //check the value of the bootstrap variable
285 jfw::FileStatus s
= checkFileURL(sVendor
);
288 //This bootstrap parameter can contain a relative URL
289 OUString sAbsoluteUrl
;
290 OUString sBaseDir
= getLibraryLocation();
291 if (File::getAbsoluteFileURL(sBaseDir
, sVendor
, sAbsoluteUrl
)
293 throw FrameworkException(
295 "[Java framework] Invalid value for bootstrap variable: "
296 UNO_JAVA_JFW_VENDOR_SETTINGS
);
297 sVendor
= sAbsoluteUrl
;
298 s
= checkFileURL(sVendor
);
299 if (s
== jfw::FILE_INVALID
|| s
== jfw::FILE_DOES_NOT_EXIST
)
301 throw FrameworkException(
303 "[Java framework] Invalid value for bootstrap variable: "
304 UNO_JAVA_JFW_VENDOR_SETTINGS
);
309 "Using bootstrap parameter " UNO_JAVA_JFW_VENDOR_SETTINGS
" = "
315 OUString
BootParams::getJREHome()
319 bool bJRE
= Bootstrap()->getFrom(UNO_JAVA_JFW_JREHOME
, sJRE
);
320 bool bEnvJRE
= Bootstrap()->getFrom(UNO_JAVA_JFW_ENV_JREHOME
, sEnvJRE
);
324 throw FrameworkException(
326 "[Java framework] Both bootstrap parameter "
327 UNO_JAVA_JFW_JREHOME
" and "
328 UNO_JAVA_JFW_ENV_JREHOME
" are set. However only one of them can be set."
329 "Check bootstrap parameters: environment variables, command line "
330 "arguments, rc/ini files for executable and java framework library.");
334 const char * pJRE
= getenv("JAVA_HOME");
337 throw FrameworkException(
339 "[Java framework] Both bootstrap parameter "
340 UNO_JAVA_JFW_ENV_JREHOME
" is set, but the environment variable "
341 "JAVA_HOME is not set.");
344 OUString usJRE
= OStringToOUString(osJRE
, osl_getThreadTextEncoding());
345 if (File::getFileURLFromSystemPath(usJRE
, sJRE
) != File::E_None
)
346 throw FrameworkException(
348 "[Java framework] Error in function BootParams::getJREHome() "
352 "Using bootstrap parameter " UNO_JAVA_JFW_ENV_JREHOME
353 " with JAVA_HOME = " << pJRE
);
355 else if (getMode() == JFW_MODE_DIRECT
&& !bJRE
)
357 throw FrameworkException(
359 "[Java framework] The bootstrap parameter "
360 UNO_JAVA_JFW_ENV_JREHOME
" or " UNO_JAVA_JFW_JREHOME
361 " must be set in direct mode.");
366 "Using bootstrap parameter " UNO_JAVA_JFW_JREHOME
" = " << sJRE
);
370 OUString
BootParams::getClasspathUrls()
373 Bootstrap()->getFrom( UNO_JAVA_JFW_CLASSPATH_URLS
, sParams
);
376 "Using bootstrap parameter " UNO_JAVA_JFW_CLASSPATH_URLS
" = "
383 static bool g_bMode
= false;
384 static JFW_MODE g_mode
= JFW_MODE_APPLICATION
;
388 //check if either of the "direct mode" bootstrap variables is set
389 bool bDirectMode
= true;
391 const rtl::Bootstrap
* aBoot
= Bootstrap();
392 if (!aBoot
->getFrom(UNO_JAVA_JFW_JREHOME
, sValue
))
394 if (!aBoot
->getFrom(UNO_JAVA_JFW_ENV_JREHOME
, sValue
))
396 if (!aBoot
->getFrom(UNO_JAVA_JFW_CLASSPATH
, sValue
))
398 if (!aBoot
->getFrom(UNO_JAVA_JFW_ENV_CLASSPATH
, sValue
))
400 OUString sParams
= UNO_JAVA_JFW_PARAMETER
+
402 if (!aBoot
->getFrom(sParams
, sValue
))
412 g_mode
= JFW_MODE_DIRECT
;
414 g_mode
= JFW_MODE_APPLICATION
;
421 OUString
getApplicationClassPath()
423 OSL_ASSERT(getMode() == JFW_MODE_APPLICATION
);
424 OUString sParams
= BootParams::getClasspathUrls();
425 if (sParams
.isEmpty())
432 OUString
token( sParams
.getToken( 0, ' ', index
).trim() );
433 if (!token
.isEmpty())
435 OUString systemPathElement
;
436 oslFileError rc
= osl_getSystemPathFromFileURL(
437 token
.pData
, &systemPathElement
.pData
);
438 OSL_ASSERT( rc
== osl_File_E_None
);
439 if (rc
== osl_File_E_None
&& !systemPathElement
.isEmpty())
441 if (buf
.getLength() > 0)
442 buf
.append( SAL_PATHSEPARATOR
);
443 buf
.append( systemPathElement
);
448 return buf
.makeStringAndClear();
451 OString
makeClassPathOption(std::u16string_view sUserClassPath
)
453 //Compose the class path
455 OUStringBuffer
sBufCP(4096);
457 // append all user selected jars to the class path
458 if (!sUserClassPath
.empty())
459 sBufCP
.append(sUserClassPath
);
461 //append all jar libraries and components to the class path
462 OUString sAppCP
= getApplicationClassPath();
463 if (!sAppCP
.isEmpty())
465 if (!sUserClassPath
.empty())
467 sBufCP
.append(SAL_PATHSEPARATOR
);
469 sBufCP
.append(sAppCP
);
472 sPaths
= OUStringToOString(sBufCP
.makeStringAndClear(), PathEncoding());
473 if (sPaths
.isEmpty()) {
477 OString sOptionClassPath
= "-Djava.class.path=" + sPaths
;
478 return sOptionClassPath
;
481 OString
getUserSettingsPath()
483 return getSettingsPath(BootParams::getUserData());
486 OString
getSharedSettingsPath()
488 return getSettingsPath(BootParams::getSharedData());
491 OString
getSettingsPath( const OUString
& sURL
)
496 if (osl_getSystemPathFromFileURL(sURL
.pData
,
497 & sPath
.pData
) != osl_File_E_None
)
498 throw FrameworkException(
500 "[Java framework] Error in function ::getSettingsPath (fwkbase.cxx).");
501 return OUStringToOString(sPath
, PathEncoding());
504 OString
getVendorSettingsPath()
506 return getVendorSettingsPath(BootParams::getVendorSettings());
509 void setJavaSelected()
514 bool wasJavaSelectedInSameProcess()
516 //g_setJavaProcId not set means no Java selected
523 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */