LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / jvmfwk / source / fwkbase.cxx
blobbb5df10a9c4dda3670c53078b590f21a33d14dbd
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/file.hxx>
25 #include <osl/thread.hxx>
26 #include "framework.hxx"
27 #include <fwkutil.hxx>
28 #include <elements.hxx>
29 #include <fwkbase.hxx>
31 using namespace osl;
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"
42 namespace jfw
44 static bool g_bJavaSet = false;
46 namespace {
48 #if defined _WIN32
49 // The paths are used in libxml. On Windows, it takes UTF-8 paths.
50 constexpr rtl_TextEncoding PathEncoding() { return RTL_TEXTENCODING_UTF8; }
51 #else
52 rtl_TextEncoding PathEncoding() { return osl_getThreadTextEncoding(); }
53 #endif
55 OString getVendorSettingsPath(OUString const & sURL)
57 if (sURL.isEmpty())
58 return OString();
59 OUString sSystemPathSettings;
60 if (osl_getSystemPathFromFileURL(sURL.pData,
61 & sSystemPathSettings.pData) != osl_File_E_None)
62 throw FrameworkException(
63 JFW_E_ERROR,
64 "[Java framework] Error in function getVendorSettingsPath (fwkbase.cxx) ");
65 OString osSystemPathSettings = OUStringToOString(sSystemPathSettings, PathEncoding());
66 return osSystemPathSettings;
69 OUString getParam(OUString const & name)
71 OUString retVal;
72 bool b = Bootstrap()->getFrom(name, retVal);
73 SAL_INFO(
74 "jfw",
75 "Using bootstrap parameter " << name << " = \"" << retVal << "\""
76 << (b ? "" : " (undefined)"));
77 return retVal;
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, ' ');
88 }//blind namespace
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())
104 return;
106 m_xmlDocVendorSettings = xmlParseFile(sSettingsPath.getStr());
107 if (m_xmlDocVendorSettings == nullptr)
108 throw FrameworkException(
109 JFW_E_ERROR,
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));
117 if (res == -1)
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 *>(
128 OString(
129 "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"" + osVendor
130 + "\"]/jf:minVersion").getStr()),
131 m_xmlPathContextVendorSettings);
132 if (xmlXPathNodeSetIsEmpty(pathObject->nodesetval))
134 return {
136 #if defined MACOSX && defined __aarch64__
137 "17",
138 #else
139 "1.8.0",
140 #endif
141 ""};
144 VersionInfo aVersionInfo;
145 //Get minVersion
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();
157 else
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);
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 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);
210 cur = cur->next;
213 return aVersionInfo;
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);
223 OUString sValue;
224 if (Bootstrap()->getFrom(sName, sValue))
226 OString sParam =
227 OUStringToOString(sValue, osl_getThreadTextEncoding());
228 vecParams.push_back(sParam);
229 SAL_INFO(
230 "jfw.level2",
231 "Using bootstrap parameter " << sName << " = " << sParam);
233 else
234 break;
236 return vecParams;
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()
251 OString sClassPath;
252 OUString sCP;
253 if (Bootstrap()->getFrom( UNO_JAVA_JFW_CLASSPATH, sCP ))
255 sClassPath = OUStringToOString(sCP, PathEncoding());
256 SAL_INFO(
257 "jfw.level2",
258 "Using bootstrap parameter " UNO_JAVA_JFW_CLASSPATH " = "
259 << sClassPath);
262 OUString sEnvCP;
263 if (Bootstrap()->getFrom( UNO_JAVA_JFW_ENV_CLASSPATH, sEnvCP ))
265 char * pCp = getenv("CLASSPATH");
266 if (pCp)
268 sClassPath += OStringChar(SAL_PATHSEPARATOR) + pCp;
270 SAL_INFO(
271 "jfw.level2",
272 "Using bootstrap parameter " UNO_JAVA_JFW_ENV_CLASSPATH
273 " and class path is: " << (pCp ? pCp : ""));
276 return sClassPath;
279 OUString BootParams::getVendorSettings()
281 OUString sVendor;
282 if (Bootstrap()->getFrom(UNO_JAVA_JFW_VENDOR_SETTINGS, sVendor))
284 //check the value of the bootstrap variable
285 jfw::FileStatus s = checkFileURL(sVendor);
286 if (s != FILE_OK)
288 //This bootstrap parameter can contain a relative URL
289 OUString sAbsoluteUrl;
290 OUString sBaseDir = getLibraryLocation();
291 if (File::getAbsoluteFileURL(sBaseDir, sVendor, sAbsoluteUrl)
292 != File::E_None)
293 throw FrameworkException(
294 JFW_E_CONFIGURATION,
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(
302 JFW_E_CONFIGURATION,
303 "[Java framework] Invalid value for bootstrap variable: "
304 UNO_JAVA_JFW_VENDOR_SETTINGS);
307 SAL_INFO(
308 "jfw.level2",
309 "Using bootstrap parameter " UNO_JAVA_JFW_VENDOR_SETTINGS " = "
310 << sVendor);
312 return sVendor;
315 OUString BootParams::getJREHome()
317 OUString sJRE;
318 OUString sEnvJRE;
319 bool bJRE = Bootstrap()->getFrom(UNO_JAVA_JFW_JREHOME, sJRE);
320 bool bEnvJRE = Bootstrap()->getFrom(UNO_JAVA_JFW_ENV_JREHOME, sEnvJRE);
322 if (bJRE && bEnvJRE)
324 throw FrameworkException(
325 JFW_E_CONFIGURATION,
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.");
332 else if (bEnvJRE)
334 const char * pJRE = getenv("JAVA_HOME");
335 if (pJRE == nullptr)
337 throw FrameworkException(
338 JFW_E_CONFIGURATION,
339 "[Java framework] Both bootstrap parameter "
340 UNO_JAVA_JFW_ENV_JREHOME" is set, but the environment variable "
341 "JAVA_HOME is not set.");
343 OString osJRE(pJRE);
344 OUString usJRE = OStringToOUString(osJRE, osl_getThreadTextEncoding());
345 if (File::getFileURLFromSystemPath(usJRE, sJRE) != File::E_None)
346 throw FrameworkException(
347 JFW_E_ERROR,
348 "[Java framework] Error in function BootParams::getJREHome() "
349 "(fwkbase.cxx).");
350 SAL_INFO(
351 "jfw.level2",
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(
358 JFW_E_CONFIGURATION,
359 "[Java framework] The bootstrap parameter "
360 UNO_JAVA_JFW_ENV_JREHOME" or " UNO_JAVA_JFW_JREHOME
361 " must be set in direct mode.");
364 SAL_INFO_IF(
365 bJRE, "jfw.level2",
366 "Using bootstrap parameter " UNO_JAVA_JFW_JREHOME " = " << sJRE);
367 return sJRE;
370 OUString BootParams::getClasspathUrls()
372 OUString sParams;
373 Bootstrap()->getFrom( UNO_JAVA_JFW_CLASSPATH_URLS, sParams);
374 SAL_INFO(
375 "jfw.level2",
376 "Using bootstrap parameter " UNO_JAVA_JFW_CLASSPATH_URLS " = "
377 << sParams);
378 return sParams;
381 JFW_MODE getMode()
383 static bool g_bMode = false;
384 static JFW_MODE g_mode = JFW_MODE_APPLICATION;
386 if (!g_bMode)
388 //check if either of the "direct mode" bootstrap variables is set
389 bool bDirectMode = true;
390 OUString sValue;
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 +
401 OUString::number(1);
402 if (!aBoot->getFrom(sParams, sValue))
404 bDirectMode = false;
411 if (bDirectMode)
412 g_mode = JFW_MODE_DIRECT;
413 else
414 g_mode = JFW_MODE_APPLICATION;
415 g_bMode = true;
418 return g_mode;
421 OUString getApplicationClassPath()
423 OSL_ASSERT(getMode() == JFW_MODE_APPLICATION);
424 OUString sParams = BootParams::getClasspathUrls();
425 if (sParams.isEmpty())
426 return OUString();
428 OUStringBuffer buf;
429 sal_Int32 index = 0;
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 );
447 while (index >= 0);
448 return buf.makeStringAndClear();
451 OString makeClassPathOption(std::u16string_view sUserClassPath)
453 //Compose the class path
454 OString sPaths;
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()) {
474 return "";
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)
493 if (sURL.isEmpty())
494 return OString();
495 OUString sPath;
496 if (osl_getSystemPathFromFileURL(sURL.pData,
497 & sPath.pData) != osl_File_E_None)
498 throw FrameworkException(
499 JFW_E_ERROR,
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()
511 g_bJavaSet = true;
514 bool wasJavaSelectedInSameProcess()
516 //g_setJavaProcId not set means no Java selected
517 return g_bJavaSet;
523 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */