Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "rtl/ustring.hxx"
21 : #include "rtl/ustrbuf.hxx"
22 : #include "rtl/uri.hxx"
23 : #include "osl/thread.hxx"
24 : #include "osl/process.h"
25 : #include "libxml/xpathInternals.h"
26 : #include "osl/file.hxx"
27 : #include "osl/module.hxx"
28 : #include "framework.hxx"
29 : #include "fwkutil.hxx"
30 : #include "elements.hxx"
31 : #include "fwkbase.hxx"
32 :
33 : using namespace osl;
34 :
35 :
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"
43 :
44 : namespace jfw
45 : {
46 : bool g_bJavaSet = false;
47 :
48 : namespace {
49 :
50 155 : OString getVendorSettingsPath(OUString const & sURL)
51 : {
52 155 : if (sURL.isEmpty())
53 0 : return OString();
54 155 : OUString sSystemPathSettings;
55 155 : if (osl_getSystemPathFromFileURL(sURL.pData,
56 155 : & sSystemPathSettings.pData) != osl_File_E_None)
57 : throw FrameworkException(
58 : JFW_E_ERROR,
59 : OString("[Java framework] Error in function "
60 0 : "getVendorSettingsPath (fwkbase.cxx) "));
61 : OString osSystemPathSettings =
62 310 : OUStringToOString(sSystemPathSettings,osl_getThreadTextEncoding());
63 310 : return osSystemPathSettings;
64 : }
65 :
66 81 : OUString getParam(OUString const & name)
67 : {
68 81 : OUString retVal;
69 81 : bool b = Bootstrap::get()->getFrom(name, retVal);
70 : SAL_INFO(
71 : "jfw",
72 : "Using bootstrap parameter " << name << " = \"" << retVal << "\""
73 : << (b ? "" : " (undefined)"));
74 81 : return retVal;
75 : }
76 :
77 81 : OUString getParamFirstUrl(OUString const & name)
78 : {
79 : // Some parameters can consist of multiple URLs (separated by space
80 : // characters, although trim() harmlessly also removes other white-space),
81 : // of which only the first is used:
82 81 : sal_Int32 i = 0;
83 81 : return getParam(name).trim().getToken(0, ' ', i);
84 : }
85 :
86 : }//blind namespace
87 :
88 :
89 154 : VendorSettings::VendorSettings():
90 154 : m_xmlDocVendorSettingsFileUrl(BootParams::getVendorSettings())
91 : {
92 : OString sMsgExc("[Java framework] Error in constructor "
93 154 : "VendorSettings::VendorSettings() (fwkbase.cxx)");
94 : //Prepare the xml document and context
95 308 : OString sSettingsPath = getVendorSettingsPath(m_xmlDocVendorSettingsFileUrl);
96 154 : if (sSettingsPath.isEmpty())
97 : {
98 : OString sMsg("[Java framework] A vendor settings file was not specified."
99 0 : "Check the bootstrap parameter " UNO_JAVA_JFW_VENDOR_SETTINGS ".");
100 : OSL_FAIL(sMsg.getStr());
101 0 : throw FrameworkException(JFW_E_CONFIGURATION, sMsg);
102 : }
103 154 : if (!sSettingsPath.isEmpty())
104 : {
105 154 : m_xmlDocVendorSettings = xmlParseFile(sSettingsPath.getStr());
106 154 : if (m_xmlDocVendorSettings == NULL)
107 : throw FrameworkException(
108 : JFW_E_ERROR,
109 : OString("[Java framework] Error while parsing file: ")
110 0 : + sSettingsPath + OString("."));
111 :
112 154 : m_xmlPathContextVendorSettings = xmlXPathNewContext(m_xmlDocVendorSettings);
113 : int res = xmlXPathRegisterNs(
114 : m_xmlPathContextVendorSettings, reinterpret_cast<xmlChar const *>("jf"),
115 154 : reinterpret_cast<xmlChar const *>(NS_JAVA_FRAMEWORK));
116 154 : if (res == -1)
117 0 : throw FrameworkException(JFW_E_ERROR, sMsgExc);
118 154 : }
119 154 : }
120 :
121 174 : VersionInfo VendorSettings::getVersionInformation(const OUString & sVendor)
122 : {
123 : OSL_ASSERT(!sVendor.isEmpty());
124 174 : VersionInfo aVersionInfo;
125 348 : OString osVendor = OUStringToOString(sVendor, RTL_TEXTENCODING_UTF8);
126 : //Get minVersion
127 : OString sExpresion = OString(
128 348 : "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"") +
129 696 : osVendor + OString("\"]/jf:minVersion");
130 :
131 348 : CXPathObjectPtr xPathObjectMin;
132 348 : xPathObjectMin =
133 174 : xmlXPathEvalExpression(reinterpret_cast<xmlChar const *>(sExpresion.getStr()),
134 174 : m_xmlPathContextVendorSettings);
135 174 : if (xmlXPathNodeSetIsEmpty(xPathObjectMin->nodesetval))
136 : {
137 0 : aVersionInfo.sMinVersion.clear();
138 : }
139 : else
140 : {
141 174 : CXmlCharPtr sVersion;
142 174 : sVersion = xmlNodeListGetString(
143 : m_xmlDocVendorSettings,
144 348 : xPathObjectMin->nodesetval->nodeTab[0]->xmlChildrenNode, 1);
145 348 : OString osVersion(sVersion);
146 348 : aVersionInfo.sMinVersion = OStringToOUString(
147 348 : osVersion, RTL_TEXTENCODING_UTF8);
148 : }
149 :
150 : //Get maxVersion
151 696 : sExpresion = OString("/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"") +
152 870 : osVendor + OString("\"]/jf:maxVersion");
153 348 : CXPathObjectPtr xPathObjectMax;
154 348 : xPathObjectMax = xmlXPathEvalExpression(
155 174 : reinterpret_cast<xmlChar const *>(sExpresion.getStr()),
156 174 : m_xmlPathContextVendorSettings);
157 174 : if (xmlXPathNodeSetIsEmpty(xPathObjectMax->nodesetval))
158 : {
159 174 : aVersionInfo.sMaxVersion.clear();
160 : }
161 : else
162 : {
163 0 : CXmlCharPtr sVersion;
164 0 : sVersion = xmlNodeListGetString(
165 : m_xmlDocVendorSettings,
166 0 : xPathObjectMax->nodesetval->nodeTab[0]->xmlChildrenNode, 1);
167 0 : OString osVersion(sVersion);
168 0 : aVersionInfo.sMaxVersion = OStringToOUString(
169 0 : osVersion, RTL_TEXTENCODING_UTF8);
170 : }
171 :
172 : //Get excludeVersions
173 696 : sExpresion = OString("/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"") +
174 870 : osVendor + OString("\"]/jf:excludeVersions/jf:version");
175 348 : CXPathObjectPtr xPathObjectVersions;
176 348 : xPathObjectVersions =
177 174 : xmlXPathEvalExpression(reinterpret_cast<xmlChar const *>(sExpresion.getStr()),
178 174 : m_xmlPathContextVendorSettings);
179 174 : if (!xmlXPathNodeSetIsEmpty(xPathObjectVersions->nodesetval))
180 : {
181 0 : xmlNode* cur = xPathObjectVersions->nodesetval->nodeTab[0];
182 0 : while (cur != NULL)
183 : {
184 0 : if (cur->type == XML_ELEMENT_NODE )
185 : {
186 0 : if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("version")) == 0)
187 : {
188 0 : CXmlCharPtr sVersion;
189 0 : sVersion = xmlNodeListGetString(
190 0 : m_xmlDocVendorSettings, cur->xmlChildrenNode, 1);
191 0 : OString osVersion(sVersion);
192 : OUString usVersion = OStringToOUString(
193 0 : osVersion, RTL_TEXTENCODING_UTF8);
194 0 : aVersionInfo.addExcludeVersion(usVersion);
195 : }
196 : }
197 0 : cur = cur->next;
198 : }
199 : }
200 348 : return aVersionInfo;
201 : }
202 :
203 77 : std::vector<OUString> VendorSettings::getSupportedVendors()
204 : {
205 77 : std::vector<OUString> vecVendors;
206 : //get the nodeset for the vendor elements
207 154 : jfw::CXPathObjectPtr result;
208 77 : result = xmlXPathEvalExpression(
209 : reinterpret_cast<xmlChar const *>("/jf:javaSelection/jf:vendorInfos/jf:vendor"),
210 77 : m_xmlPathContextVendorSettings);
211 77 : if (!xmlXPathNodeSetIsEmpty(result->nodesetval))
212 : {
213 : //get the values of the vendor elements + name attribute
214 77 : xmlNode* cur = result->nodesetval->nodeTab[0];
215 1232 : while (cur != NULL)
216 : {
217 : //between vendor elements are also text elements
218 1078 : if (cur->type == XML_ELEMENT_NODE)
219 : {
220 539 : jfw::CXmlCharPtr sAttrVendor(xmlGetProp(cur, reinterpret_cast<xmlChar const *>("name")));
221 539 : vecVendors.push_back(sAttrVendor);
222 : }
223 1078 : cur = cur->next;
224 : }
225 : }
226 154 : return vecVendors;
227 : }
228 :
229 3 : ::std::vector<OString> BootParams::getVMParameters()
230 : {
231 3 : ::std::vector<OString> vecParams;
232 :
233 3 : for (sal_Int32 i = 1; ; i++)
234 : {
235 3 : OUString sName = UNO_JAVA_JFW_PARAMETER + OUString::number(i);
236 3 : OUString sValue;
237 3 : if (Bootstrap::get()->getFrom(sName, sValue))
238 : {
239 : OString sParam =
240 0 : OUStringToOString(sValue, osl_getThreadTextEncoding());
241 0 : vecParams.push_back(sParam);
242 : SAL_INFO(
243 : "jfw.level2",
244 0 : "Using bootstrap parameter " << sName << " = " << sParam);
245 : }
246 : else
247 3 : break;
248 0 : }
249 3 : return vecParams;
250 : }
251 :
252 53 : OUString BootParams::getUserData()
253 : {
254 53 : return getParamFirstUrl("UNO_JAVA_JFW_USER_DATA");
255 : }
256 :
257 28 : OUString BootParams::getSharedData()
258 : {
259 28 : return getParamFirstUrl("UNO_JAVA_JFW_SHARED_DATA");
260 : }
261 :
262 3 : OString BootParams::getClasspath()
263 : {
264 3 : OString sClassPath;
265 6 : OUString sCP;
266 9 : if (Bootstrap::get()->getFrom(
267 : OUString(UNO_JAVA_JFW_CLASSPATH),
268 9 : sCP))
269 : {
270 0 : sClassPath = OUStringToOString(sCP, osl_getThreadTextEncoding());
271 : SAL_INFO(
272 : "jfw.level2",
273 : "Using bootstrap parameter " UNO_JAVA_JFW_CLASSPATH " = "
274 : << sClassPath);
275 : }
276 :
277 6 : OUString sEnvCP;
278 9 : if (Bootstrap::get()->getFrom(
279 : OUString(UNO_JAVA_JFW_ENV_CLASSPATH),
280 9 : sEnvCP))
281 : {
282 2 : char * pCp = getenv("CLASSPATH");
283 2 : if (pCp)
284 : {
285 0 : char szSep[] = {SAL_PATHSEPARATOR,0};
286 0 : sClassPath += OString(szSep) + OString(pCp);
287 : }
288 : SAL_INFO(
289 : "jfw.level2",
290 : "Using bootstrap parameter " UNO_JAVA_JFW_ENV_CLASSPATH
291 : " and class path is: " << (pCp ? pCp : ""));
292 : }
293 :
294 6 : return sClassPath;
295 : }
296 :
297 155 : OUString BootParams::getVendorSettings()
298 : {
299 155 : OUString sVendor;
300 : OUString sName(
301 310 : UNO_JAVA_JFW_VENDOR_SETTINGS);
302 155 : if (Bootstrap::get()->getFrom(sName ,sVendor))
303 : {
304 : //check the value of the bootstrap variable
305 155 : jfw::FileStatus s = checkFileURL(sVendor);
306 155 : if (s != FILE_OK)
307 : {
308 : //This bootstrap parameter can contain a relative URL
309 0 : OUString sAbsoluteUrl;
310 0 : OUString sBaseDir = getLibraryLocation();
311 0 : if (File::getAbsoluteFileURL(sBaseDir, sVendor, sAbsoluteUrl)
312 : != File::E_None)
313 : throw FrameworkException(
314 : JFW_E_CONFIGURATION,
315 : OString("[Java framework] Invalid value for bootstrap variable: "
316 0 : UNO_JAVA_JFW_VENDOR_SETTINGS));
317 0 : sVendor = sAbsoluteUrl;
318 0 : s = checkFileURL(sVendor);
319 0 : if (s == jfw::FILE_INVALID || s == jfw::FILE_DOES_NOT_EXIST)
320 : {
321 : throw FrameworkException(
322 : JFW_E_CONFIGURATION,
323 : OString("[Java framework] Invalid value for bootstrap variable: "
324 0 : UNO_JAVA_JFW_VENDOR_SETTINGS));
325 0 : }
326 : }
327 : SAL_INFO(
328 : "jfw.level2",
329 : "Using bootstrap parameter " UNO_JAVA_JFW_VENDOR_SETTINGS " = "
330 : << sVendor);
331 : }
332 310 : return sVendor;
333 : }
334 :
335 73 : OUString BootParams::getJREHome()
336 : {
337 73 : OUString sJRE;
338 146 : OUString sEnvJRE;
339 73 : bool bJRE = Bootstrap::get()->getFrom(
340 146 : OUString(UNO_JAVA_JFW_JREHOME) ,sJRE);
341 73 : bool bEnvJRE = Bootstrap::get()->getFrom(
342 146 : OUString(UNO_JAVA_JFW_ENV_JREHOME) ,sEnvJRE);
343 :
344 73 : if (bJRE && bEnvJRE)
345 : {
346 : throw FrameworkException(
347 : JFW_E_CONFIGURATION,
348 : OString("[Java framework] Both bootstrap parameter "
349 : UNO_JAVA_JFW_JREHOME" and "
350 : UNO_JAVA_JFW_ENV_JREHOME" are set. However only one of them can be set."
351 : "Check bootstrap parameters: environment variables, command line "
352 0 : "arguments, rc/ini files for executable and java framework library."));
353 : }
354 73 : else if (bEnvJRE)
355 : {
356 73 : const char * pJRE = getenv("JAVA_HOME");
357 73 : if (pJRE == NULL)
358 : {
359 : throw FrameworkException(
360 : JFW_E_CONFIGURATION,
361 : OString("[Java framework] Both bootstrap parameter "
362 : UNO_JAVA_JFW_ENV_JREHOME" is set, but the environment variable "
363 0 : "JAVA_HOME is not set."));
364 : }
365 73 : OString osJRE(pJRE);
366 146 : OUString usJRE = OStringToOUString(osJRE, osl_getThreadTextEncoding());
367 73 : if (File::getFileURLFromSystemPath(usJRE, sJRE) != File::E_None)
368 : throw FrameworkException(
369 : JFW_E_ERROR,
370 : OString("[Java framework] Error in function BootParams::getJREHome() "
371 0 : "(fwkbase.cxx)."));
372 : SAL_INFO(
373 : "jfw.level2",
374 : "Using bootstrap parameter " UNO_JAVA_JFW_ENV_JREHOME
375 73 : " with JAVA_HOME = " << pJRE);
376 : }
377 0 : else if (getMode() == JFW_MODE_DIRECT
378 0 : && !bEnvJRE
379 0 : && !bJRE)
380 : {
381 : throw FrameworkException(
382 : JFW_E_CONFIGURATION,
383 : OString("[Java framework] The bootstrap parameter "
384 : UNO_JAVA_JFW_ENV_JREHOME" or " UNO_JAVA_JFW_JREHOME
385 0 : " must be set in direct mode."));
386 : }
387 :
388 : SAL_INFO_IF(
389 : bJRE, "jfw.level2",
390 : "Using bootstrap parameter " UNO_JAVA_JFW_JREHOME " = " << sJRE);
391 146 : return sJRE;
392 : }
393 :
394 0 : OUString BootParams::getClasspathUrls()
395 : {
396 0 : OUString sParams;
397 0 : Bootstrap::get()->getFrom(
398 : OUString(UNO_JAVA_JFW_CLASSPATH_URLS),
399 0 : sParams);
400 : SAL_INFO(
401 : "jfw.level2",
402 : "Using bootstrap parameter " UNO_JAVA_JFW_CLASSPATH_URLS " = "
403 : << sParams);
404 0 : return sParams;
405 : }
406 :
407 281 : JFW_MODE getMode()
408 : {
409 : static bool g_bMode = false;
410 : static JFW_MODE g_mode = JFW_MODE_APPLICATION;
411 :
412 281 : if (!g_bMode)
413 : {
414 : //check if either of the "direct mode" bootstrap variables is set
415 77 : bool bDirectMode = true;
416 77 : OUString sValue;
417 77 : const rtl::Bootstrap * aBoot = Bootstrap::get();
418 154 : OUString sJREHome(UNO_JAVA_JFW_JREHOME);
419 77 : if (!aBoot->getFrom(sJREHome, sValue))
420 : {
421 77 : OUString sEnvJRE(UNO_JAVA_JFW_ENV_JREHOME);
422 77 : if (!aBoot->getFrom(sEnvJRE, sValue))
423 : {
424 4 : OUString sClasspath(UNO_JAVA_JFW_CLASSPATH);
425 4 : if (!aBoot->getFrom(sClasspath, sValue))
426 : {
427 4 : OUString sEnvClasspath(UNO_JAVA_JFW_ENV_CLASSPATH);
428 4 : if (!aBoot->getFrom(sEnvClasspath, sValue))
429 : {
430 8 : OUString sParams = UNO_JAVA_JFW_PARAMETER +
431 12 : OUString::number(1);
432 4 : if (!aBoot->getFrom(sParams, sValue))
433 : {
434 4 : bDirectMode = false;
435 4 : }
436 4 : }
437 4 : }
438 77 : }
439 : }
440 :
441 77 : if (bDirectMode)
442 73 : g_mode = JFW_MODE_DIRECT;
443 : else
444 4 : g_mode = JFW_MODE_APPLICATION;
445 154 : g_bMode = true;
446 : }
447 :
448 281 : return g_mode;
449 : }
450 :
451 0 : OUString getApplicationClassPath()
452 : {
453 : OSL_ASSERT(getMode() == JFW_MODE_APPLICATION);
454 0 : OUString retVal;
455 0 : OUString sParams = BootParams::getClasspathUrls();
456 0 : if (sParams.isEmpty())
457 0 : return retVal;
458 :
459 0 : OUStringBuffer buf;
460 0 : sal_Int32 index = 0;
461 0 : const char szClassPathSep[] = {SAL_PATHSEPARATOR,0};
462 0 : do
463 : {
464 0 : OUString token( sParams.getToken( 0, ' ', index ).trim() );
465 0 : if (!token.isEmpty())
466 : {
467 0 : OUString systemPathElement;
468 : oslFileError rc = osl_getSystemPathFromFileURL(
469 0 : token.pData, &systemPathElement.pData );
470 : OSL_ASSERT( rc == osl_File_E_None );
471 0 : if (rc == osl_File_E_None && !systemPathElement.isEmpty())
472 : {
473 0 : if (buf.getLength() > 0)
474 0 : buf.append( szClassPathSep );
475 0 : buf.append( systemPathElement );
476 0 : }
477 0 : }
478 : }
479 0 : while (index >= 0);
480 0 : return buf.makeStringAndClear();
481 : }
482 :
483 0 : OString makeClassPathOption(OUString const & sUserClassPath)
484 : {
485 : //Compose the class path
486 0 : OString sPaths;
487 0 : OUStringBuffer sBufCP(4096);
488 :
489 : // append all user selected jars to the class path
490 0 : if (!sUserClassPath.isEmpty())
491 0 : sBufCP.append(sUserClassPath);
492 :
493 : //append all jar libraries and components to the class path
494 0 : OUString sAppCP = getApplicationClassPath();
495 0 : if (!sAppCP.isEmpty())
496 : {
497 0 : if (!sUserClassPath.isEmpty())
498 : {
499 0 : char szSep[] = {SAL_PATHSEPARATOR,0};
500 0 : sBufCP.appendAscii(szSep);
501 : }
502 0 : sBufCP.append(sAppCP);
503 : }
504 :
505 0 : sPaths = OUStringToOString(
506 0 : sBufCP.makeStringAndClear(), osl_getThreadTextEncoding());
507 :
508 0 : OString sOptionClassPath("-Djava.class.path=");
509 0 : sOptionClassPath += sPaths;
510 0 : return sOptionClassPath;
511 : }
512 :
513 21 : OString getUserSettingsPath()
514 : {
515 21 : return getSettingsPath(BootParams::getUserData());
516 : }
517 :
518 0 : OString getSharedSettingsPath()
519 : {
520 0 : return getSettingsPath(BootParams::getSharedData());
521 : }
522 :
523 21 : OString getSettingsPath( const OUString & sURL)
524 : {
525 21 : if (sURL.isEmpty())
526 0 : return OString();
527 21 : OUString sPath;
528 21 : if (osl_getSystemPathFromFileURL(sURL.pData,
529 21 : & sPath.pData) != osl_File_E_None)
530 : throw FrameworkException(
531 : JFW_E_ERROR, OString(
532 0 : "[Java framework] Error in function ::getSettingsPath (fwkbase.cxx)."));
533 21 : return OUStringToOString(sPath,osl_getThreadTextEncoding());
534 : }
535 :
536 1 : OString getVendorSettingsPath()
537 : {
538 1 : return getVendorSettingsPath(BootParams::getVendorSettings());
539 : }
540 :
541 4 : void setJavaSelected()
542 : {
543 4 : g_bJavaSet = true;
544 4 : }
545 :
546 0 : bool wasJavaSelectedInSameProcess()
547 : {
548 : //g_setJavaProcId not set means no Java selected
549 0 : if (g_bJavaSet)
550 0 : return true;
551 0 : return false;
552 : }
553 :
554 :
555 : }
556 :
557 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|