Get the style color and number just once
[LibreOffice.git] / jvmfwk / source / fwkbase.cxx
blob47deb729f8110413232e856ff774c44cc75dd2a3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/diagnose.h>
25 #include <osl/file.hxx>
26 #include <osl/thread.hxx>
27 #include <o3tl/string_view.hxx>
28 #include "framework.hxx"
29 #include <fwkutil.hxx>
30 #include <elements.hxx>
31 #include <fwkbase.hxx>
33 using namespace osl;
36 #define UNO_JAVA_JFW_PARAMETER "UNO_JAVA_JFW_PARAMETER_"
37 #define UNO_JAVA_JFW_JREHOME "UNO_JAVA_JFW_JREHOME"
38 #define UNO_JAVA_JFW_ENV_JREHOME "UNO_JAVA_JFW_ENV_JREHOME"
39 #define UNO_JAVA_JFW_CLASSPATH "UNO_JAVA_JFW_CLASSPATH"
40 #define UNO_JAVA_JFW_ENV_CLASSPATH "UNO_JAVA_JFW_ENV_CLASSPATH"
41 #define UNO_JAVA_JFW_CLASSPATH_URLS "UNO_JAVA_JFW_CLASSPATH_URLS"
42 #define UNO_JAVA_JFW_VENDOR_SETTINGS "UNO_JAVA_JFW_VENDOR_SETTINGS"
44 namespace jfw
46 static bool g_bJavaSet = false;
48 namespace {
50 #if defined _WIN32
51 // The paths are used in libxml. On Windows, it takes UTF-8 paths.
52 constexpr rtl_TextEncoding PathEncoding() { return RTL_TEXTENCODING_UTF8; }
53 #else
54 rtl_TextEncoding PathEncoding() { return osl_getThreadTextEncoding(); }
55 #endif
57 OString getVendorSettingsPath(OUString const & sURL)
59 if (sURL.isEmpty())
60 return OString();
61 OUString sSystemPathSettings;
62 if (osl_getSystemPathFromFileURL(sURL.pData,
63 & sSystemPathSettings.pData) != osl_File_E_None)
64 throw FrameworkException(
65 JFW_E_ERROR,
66 "[Java framework] Error in function getVendorSettingsPath (fwkbase.cxx) "_ostr);
67 OString osSystemPathSettings = OUStringToOString(sSystemPathSettings, PathEncoding());
68 return osSystemPathSettings;
71 OUString getParam(OUString const & name)
73 OUString retVal;
74 bool b = Bootstrap()->getFrom(name, retVal);
75 SAL_INFO(
76 "jfw",
77 "Using bootstrap parameter " << name << " = \"" << retVal << "\""
78 << (b ? "" : " (undefined)"));
79 return retVal;
82 OUString getParamFirstUrl(OUString const & name)
84 // Some parameters can consist of multiple URLs (separated by space
85 // characters, although trim() harmlessly also removes other white-space),
86 // of which only the first is used:
87 return getParam(name).trim().getToken(0, ' ');
90 }//blind namespace
93 VendorSettings::VendorSettings()
95 OUString xmlDocVendorSettingsFileUrl(BootParams::getVendorSettings());
96 //Prepare the xml document and context
97 OString sSettingsPath = getVendorSettingsPath(xmlDocVendorSettingsFileUrl);
98 if (sSettingsPath.isEmpty())
100 OString sMsg("[Java framework] A vendor settings file was not specified."
101 "Check the bootstrap parameter " UNO_JAVA_JFW_VENDOR_SETTINGS "."_ostr);
102 SAL_WARN( "jfw", sMsg );
103 throw FrameworkException(JFW_E_CONFIGURATION, sMsg);
105 if (sSettingsPath.isEmpty())
106 return;
108 m_xmlDocVendorSettings = xmlParseFile(sSettingsPath.getStr());
109 if (m_xmlDocVendorSettings == nullptr)
110 throw FrameworkException(
111 JFW_E_ERROR,
112 OString::Concat("[Java framework] Error while parsing file: ")
113 + sSettingsPath + ".");
115 m_xmlPathContextVendorSettings = xmlXPathNewContext(m_xmlDocVendorSettings);
116 int res = xmlXPathRegisterNs(
117 m_xmlPathContextVendorSettings, reinterpret_cast<xmlChar const *>("jf"),
118 reinterpret_cast<xmlChar const *>(NS_JAVA_FRAMEWORK));
119 if (res == -1)
120 throw FrameworkException(JFW_E_ERROR,
121 "[Java framework] Error in constructor VendorSettings::VendorSettings() (fwkbase.cxx)"_ostr);
124 VersionInfo VendorSettings::getVersionInformation(std::u16string_view sVendor) const
126 OSL_ASSERT(!sVendor.empty());
127 OString osVendor = OUStringToOString(sVendor, RTL_TEXTENCODING_UTF8);
128 CXPathObjectPtr pathObject = xmlXPathEvalExpression(
129 reinterpret_cast<xmlChar const *>(
130 OString(
131 "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"" + osVendor
132 + "\"]/jf:minVersion").getStr()),
133 m_xmlPathContextVendorSettings);
134 if (xmlXPathNodeSetIsEmpty(pathObject->nodesetval))
136 return {
138 #if defined MACOSX && defined __aarch64__
139 "17",
140 #else
141 u"1.8.0"_ustr,
142 #endif
143 u""_ustr};
146 VersionInfo aVersionInfo;
147 //Get minVersion
148 OString sExpression =
149 "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"" +
150 osVendor + "\"]/jf:minVersion";
152 CXPathObjectPtr xPathObjectMin =
153 xmlXPathEvalExpression(reinterpret_cast<xmlChar const *>(sExpression.getStr()),
154 m_xmlPathContextVendorSettings);
155 if (xmlXPathNodeSetIsEmpty(xPathObjectMin->nodesetval))
157 aVersionInfo.sMinVersion.clear();
159 else
161 CXmlCharPtr sVersion = xmlNodeListGetString(
162 m_xmlDocVendorSettings,
163 xPathObjectMin->nodesetval->nodeTab[0]->xmlChildrenNode, 1);
164 aVersionInfo.sMinVersion = sVersion;
167 //Get maxVersion
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();
177 else
179 CXmlCharPtr sVersion = xmlNodeListGetString(
180 m_xmlDocVendorSettings,
181 xPathObjectMax->nodesetval->nodeTab[0]->xmlChildrenNode, 1);
182 aVersionInfo.sMaxVersion = sVersion;
185 //Get excludeVersions
186 sExpression = "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"" +
187 osVendor + "\"]/jf:excludeVersions/jf:version";
188 CXPathObjectPtr xPathObjectVersions =
189 xmlXPathEvalExpression(reinterpret_cast<xmlChar const *>(sExpression.getStr()),
190 m_xmlPathContextVendorSettings);
191 if (!xmlXPathNodeSetIsEmpty(xPathObjectVersions->nodesetval))
193 xmlNode* cur = xPathObjectVersions->nodesetval->nodeTab[0];
194 while (cur != nullptr)
196 if (cur->type == XML_ELEMENT_NODE )
198 if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("version")) == 0)
200 CXmlCharPtr sVersion = xmlNodeListGetString(
201 m_xmlDocVendorSettings, cur->xmlChildrenNode, 1);
202 OUString usVersion = sVersion;
203 aVersionInfo.vecExcludeVersions.push_back(usVersion);
206 cur = cur->next;
209 return aVersionInfo;
212 ::std::vector<OString> BootParams::getVMParameters()
214 ::std::vector<OString> vecParams;
216 for (sal_Int32 i = 1; ; i++)
218 OUString sName = UNO_JAVA_JFW_PARAMETER + OUString::number(i);
219 OUString sValue;
220 if (Bootstrap()->getFrom(sName, sValue))
222 OString sParam =
223 OUStringToOString(sValue, osl_getThreadTextEncoding());
224 vecParams.push_back(sParam);
225 SAL_INFO(
226 "jfw.level2",
227 "Using bootstrap parameter " << sName << " = " << sParam);
229 else
230 break;
232 return vecParams;
235 OUString BootParams::getUserData()
237 return getParamFirstUrl(u"UNO_JAVA_JFW_USER_DATA"_ustr);
240 OUString BootParams::getSharedData()
242 return getParamFirstUrl(u"UNO_JAVA_JFW_SHARED_DATA"_ustr);
245 OString BootParams::getClasspath()
247 OString sClassPath;
248 OUString sCP;
249 if (Bootstrap()->getFrom( u"" UNO_JAVA_JFW_CLASSPATH ""_ustr, sCP ))
251 sClassPath = OUStringToOString(sCP, PathEncoding());
252 SAL_INFO(
253 "jfw.level2",
254 "Using bootstrap parameter " UNO_JAVA_JFW_CLASSPATH " = "
255 << sClassPath);
258 OUString sEnvCP;
259 if (Bootstrap()->getFrom( u"" UNO_JAVA_JFW_ENV_CLASSPATH ""_ustr, sEnvCP ))
261 char * pCp = getenv("CLASSPATH");
262 if (pCp)
264 sClassPath += OStringChar(SAL_PATHSEPARATOR) + pCp;
266 SAL_INFO(
267 "jfw.level2",
268 "Using bootstrap parameter " UNO_JAVA_JFW_ENV_CLASSPATH
269 " and class path is: " << (pCp ? pCp : ""));
272 return sClassPath;
275 OUString BootParams::getVendorSettings()
277 OUString sVendor;
278 if (Bootstrap()->getFrom(u"" UNO_JAVA_JFW_VENDOR_SETTINGS ""_ustr, sVendor))
280 //check the value of the bootstrap variable
281 jfw::FileStatus s = checkFileURL(sVendor);
282 if (s != FILE_OK)
284 //This bootstrap parameter can contain a relative URL
285 OUString sAbsoluteUrl;
286 OUString sBaseDir = getLibraryLocation();
287 if (File::getAbsoluteFileURL(sBaseDir, sVendor, sAbsoluteUrl)
288 != File::E_None)
289 throw FrameworkException(
290 JFW_E_CONFIGURATION,
291 "[Java framework] Invalid value for bootstrap variable: "
292 UNO_JAVA_JFW_VENDOR_SETTINGS ""_ostr);
293 sVendor = sAbsoluteUrl;
294 s = checkFileURL(sVendor);
295 if (s == jfw::FILE_INVALID || s == jfw::FILE_DOES_NOT_EXIST)
297 throw FrameworkException(
298 JFW_E_CONFIGURATION,
299 "[Java framework] Invalid value for bootstrap variable: "
300 UNO_JAVA_JFW_VENDOR_SETTINGS ""_ostr);
303 SAL_INFO(
304 "jfw.level2",
305 "Using bootstrap parameter " UNO_JAVA_JFW_VENDOR_SETTINGS " = "
306 << sVendor);
308 return sVendor;
311 OUString BootParams::getJREHome()
313 OUString sJRE;
314 OUString sEnvJRE;
315 bool bJRE = Bootstrap()->getFrom(u"" UNO_JAVA_JFW_JREHOME ""_ustr, sJRE);
316 bool bEnvJRE = Bootstrap()->getFrom(u"" UNO_JAVA_JFW_ENV_JREHOME ""_ustr, sEnvJRE);
318 if (bJRE && bEnvJRE)
320 throw FrameworkException(
321 JFW_E_CONFIGURATION,
322 "[Java framework] Both bootstrap parameter "
323 UNO_JAVA_JFW_JREHOME" and "
324 UNO_JAVA_JFW_ENV_JREHOME" are set. However only one of them can be set."
325 "Check bootstrap parameters: environment variables, command line "
326 "arguments, rc/ini files for executable and java framework library."_ostr);
328 else if (bEnvJRE)
330 const char * pJRE = getenv("JAVA_HOME");
331 if (pJRE == nullptr)
333 throw FrameworkException(
334 JFW_E_CONFIGURATION,
335 "[Java framework] Both bootstrap parameter "
336 UNO_JAVA_JFW_ENV_JREHOME" is set, but the environment variable "
337 "JAVA_HOME is not set."_ostr);
339 std::string_view osJRE(pJRE);
340 OUString usJRE = OStringToOUString(osJRE, osl_getThreadTextEncoding());
341 if (File::getFileURLFromSystemPath(usJRE, sJRE) != File::E_None)
342 throw FrameworkException(
343 JFW_E_ERROR,
344 "[Java framework] Error in function BootParams::getJREHome() "
345 "(fwkbase.cxx)."_ostr);
346 SAL_INFO(
347 "jfw.level2",
348 "Using bootstrap parameter " UNO_JAVA_JFW_ENV_JREHOME
349 " with JAVA_HOME = " << pJRE);
351 else if (getMode() == JFW_MODE_DIRECT && !bJRE)
353 throw FrameworkException(
354 JFW_E_CONFIGURATION,
355 "[Java framework] The bootstrap parameter "
356 UNO_JAVA_JFW_ENV_JREHOME" or " UNO_JAVA_JFW_JREHOME
357 " must be set in direct mode."_ostr);
360 SAL_INFO_IF(
361 bJRE, "jfw.level2",
362 "Using bootstrap parameter " UNO_JAVA_JFW_JREHOME " = " << sJRE);
363 return sJRE;
366 OUString BootParams::getClasspathUrls()
368 OUString sParams;
369 Bootstrap()->getFrom( u"" UNO_JAVA_JFW_CLASSPATH_URLS ""_ustr, sParams);
370 SAL_INFO(
371 "jfw.level2",
372 "Using bootstrap parameter " UNO_JAVA_JFW_CLASSPATH_URLS " = "
373 << sParams);
374 return sParams;
377 JFW_MODE getMode()
379 static bool g_bMode = false;
380 static JFW_MODE g_mode = JFW_MODE_APPLICATION;
382 if (!g_bMode)
384 //check if either of the "direct mode" bootstrap variables is set
385 bool bDirectMode = true;
386 OUString sValue;
387 const rtl::Bootstrap * aBoot = Bootstrap();
388 if (!aBoot->getFrom(u"" UNO_JAVA_JFW_JREHOME ""_ustr, sValue))
390 if (!aBoot->getFrom(u"" UNO_JAVA_JFW_ENV_JREHOME ""_ustr, sValue))
392 if (!aBoot->getFrom(u"" UNO_JAVA_JFW_CLASSPATH ""_ustr, sValue))
394 if (!aBoot->getFrom(u"" UNO_JAVA_JFW_ENV_CLASSPATH ""_ustr, sValue))
396 OUString sParams = UNO_JAVA_JFW_PARAMETER +
397 OUString::number(1);
398 if (!aBoot->getFrom(sParams, sValue))
400 bDirectMode = false;
407 if (bDirectMode)
408 g_mode = JFW_MODE_DIRECT;
409 else
410 g_mode = JFW_MODE_APPLICATION;
411 g_bMode = true;
414 return g_mode;
417 OUString getApplicationClassPath()
419 OSL_ASSERT(getMode() == JFW_MODE_APPLICATION);
420 OUString sParams = BootParams::getClasspathUrls();
421 if (sParams.isEmpty())
422 return OUString();
424 OUStringBuffer buf;
425 sal_Int32 index = 0;
428 OUString token( o3tl::trim(o3tl::getToken(sParams, 0, ' ', index )) );
429 if (!token.isEmpty())
431 OUString systemPathElement;
432 oslFileError rc = osl_getSystemPathFromFileURL(
433 token.pData, &systemPathElement.pData );
434 OSL_ASSERT( rc == osl_File_E_None );
435 if (rc == osl_File_E_None && !systemPathElement.isEmpty())
437 if (buf.getLength() > 0)
438 buf.append( SAL_PATHSEPARATOR );
439 buf.append( systemPathElement );
443 while (index >= 0);
444 return buf.makeStringAndClear();
447 OString makeClassPathOption(std::u16string_view sUserClassPath)
449 //Compose the class path
450 OString sPaths;
451 OUStringBuffer sBufCP(4096);
453 // append all user selected jars to the class path
454 if (!sUserClassPath.empty())
455 sBufCP.append(sUserClassPath);
457 //append all jar libraries and components to the class path
458 OUString sAppCP = getApplicationClassPath();
459 if (!sAppCP.isEmpty())
461 if (!sUserClassPath.empty())
463 sBufCP.append(SAL_PATHSEPARATOR);
465 sBufCP.append(sAppCP);
468 sPaths = OUStringToOString(sBufCP, PathEncoding());
469 if (sPaths.isEmpty()) {
470 return ""_ostr;
473 OString sOptionClassPath = "-Djava.class.path=" + sPaths;
474 return sOptionClassPath;
477 OString getUserSettingsPath()
479 return getSettingsPath(BootParams::getUserData());
482 OString getSharedSettingsPath()
484 return getSettingsPath(BootParams::getSharedData());
487 OString getSettingsPath( const OUString & sURL)
489 if (sURL.isEmpty())
490 return OString();
491 OUString sPath;
492 if (osl_getSystemPathFromFileURL(sURL.pData,
493 & sPath.pData) != osl_File_E_None)
494 throw FrameworkException(
495 JFW_E_ERROR,
496 "[Java framework] Error in function ::getSettingsPath (fwkbase.cxx)."_ostr);
497 return OUStringToOString(sPath, PathEncoding());
500 OString getVendorSettingsPath()
502 return getVendorSettingsPath(BootParams::getVendorSettings());
505 void setJavaSelected()
507 g_bJavaSet = true;
510 bool wasJavaSelectedInSameProcess()
512 //g_setJavaProcId not set means no Java selected
513 return g_bJavaSet;
519 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */