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 "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"
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 #define UNO_JAVA_JFW_USER_DATA "UNO_JAVA_JFW_USER_DATA"
44 #define UNO_JAVA_JFW_SHARED_DATA "UNO_JAVA_JFW_SHARED_DATA"
48 bool g_bJavaSet
= false;
52 OString
getVendorSettingsPath(OUString
const & sURL
)
56 OUString sSystemPathSettings
;
57 if (osl_getSystemPathFromFileURL(sURL
.pData
,
58 & sSystemPathSettings
.pData
) != osl_File_E_None
)
59 throw FrameworkException(
61 OString("[Java framework] Error in function "
62 "getVendorSettingsPath (fwkbase.cxx) "));
63 OString osSystemPathSettings
=
64 OUStringToOString(sSystemPathSettings
,osl_getThreadTextEncoding());
65 return osSystemPathSettings
;
68 OUString
getParam(const char * name
)
71 if (Bootstrap::get()->getFrom(OUString::createFromAscii(name
), retVal
))
73 #if OSL_DEBUG_LEVEL >=2
74 OString sValue
= OUStringToOString(retVal
, osl_getThreadTextEncoding());
75 fprintf(stderr
,"[Java framework] Using bootstrap parameter %s = %s.\n",
76 name
, sValue
.getStr());
82 OUString
getParamFirstUrl(const char * 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:
88 return getParam(name
).trim().getToken(0, ' ', i
);
94 VendorSettings::VendorSettings():
95 m_xmlDocVendorSettingsFileUrl(BootParams::getVendorSettings())
97 OString
sMsgExc("[Java framework] Error in constructor "
98 "VendorSettings::VendorSettings() (fwkbase.cxx)");
99 //Prepare the xml document and context
100 OString sSettingsPath
= getVendorSettingsPath(m_xmlDocVendorSettingsFileUrl
);
101 if (sSettingsPath
.isEmpty())
103 OString
sMsg("[Java framework] A vendor settings file was not specified."
104 "Check the bootstrap parameter " UNO_JAVA_JFW_VENDOR_SETTINGS
".");
105 OSL_FAIL(sMsg
.getStr());
106 throw FrameworkException(JFW_E_CONFIGURATION
, sMsg
);
108 if (!sSettingsPath
.isEmpty())
110 m_xmlDocVendorSettings
= xmlParseFile(sSettingsPath
.getStr());
111 if (m_xmlDocVendorSettings
== NULL
)
112 throw FrameworkException(
114 OString("[Java framework] Error while parsing file: ")
115 + sSettingsPath
+ OString("."));
117 m_xmlPathContextVendorSettings
= xmlXPathNewContext(m_xmlDocVendorSettings
);
118 int res
= xmlXPathRegisterNs(
119 m_xmlPathContextVendorSettings
, (xmlChar
*) "jf",
120 (xmlChar
*) NS_JAVA_FRAMEWORK
);
122 throw FrameworkException(JFW_E_ERROR
, sMsgExc
);
126 std::vector
<PluginLibrary
> VendorSettings::getPluginData()
128 OString
sExcMsg("[Java framework] Error in function VendorSettings::getVendorPluginURLs "
130 std::vector
<PluginLibrary
> vecPlugins
;
131 CXPathObjectPtr
result(xmlXPathEvalExpression(
132 (xmlChar
*)"/jf:javaSelection/jf:plugins/jf:library",
133 m_xmlPathContextVendorSettings
));
134 if (xmlXPathNodeSetIsEmpty(result
->nodesetval
))
135 throw FrameworkException(JFW_E_ERROR
, sExcMsg
);
137 //get the values of the library elements + vendor attribute
138 xmlNode
* cur
= result
->nodesetval
->nodeTab
[0];
142 //between library elements are also text elements
143 if (cur
->type
== XML_ELEMENT_NODE
)
145 CXmlCharPtr
sAttrVendor(xmlGetProp(cur
, (xmlChar
*) "vendor"));
146 CXmlCharPtr
sTextLibrary(
147 xmlNodeListGetString(m_xmlDocVendorSettings
,
148 cur
->xmlChildrenNode
, 1));
149 PluginLibrary plugin
;
150 OString
osVendor((sal_Char
*)(xmlChar
*) sAttrVendor
);
151 plugin
.sVendor
= OStringToOUString(osVendor
, RTL_TEXTENCODING_UTF8
);
153 //create the file URL to the library
154 OUString sUrl
= findPlugin(
155 m_xmlDocVendorSettingsFileUrl
, sTextLibrary
);
158 OString sPlugin
= OUStringToOString(
159 sTextLibrary
, osl_getThreadTextEncoding());
160 throw FrameworkException(
162 "[Java framework] The file: " + sPlugin
+ " does not exist.");
166 vecPlugins
.push_back(plugin
);
173 VersionInfo
VendorSettings::getVersionInformation(const OUString
& sVendor
)
175 OSL_ASSERT(!sVendor
.isEmpty());
176 VersionInfo aVersionInfo
;
177 OString osVendor
= OUStringToOString(sVendor
, RTL_TEXTENCODING_UTF8
);
179 OString sExpresion
= OString(
180 "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"") +
181 osVendor
+ OString("\"]/jf:minVersion");
183 CXPathObjectPtr xPathObjectMin
;
185 xmlXPathEvalExpression((xmlChar
*) sExpresion
.getStr(),
186 m_xmlPathContextVendorSettings
);
187 if (xmlXPathNodeSetIsEmpty(xPathObjectMin
->nodesetval
))
189 aVersionInfo
.sMinVersion
= OUString();
193 CXmlCharPtr sVersion
;
194 sVersion
= xmlNodeListGetString(
195 m_xmlDocVendorSettings
,
196 xPathObjectMin
->nodesetval
->nodeTab
[0]->xmlChildrenNode
, 1);
197 OString
osVersion((sal_Char
*)(xmlChar
*) sVersion
);
198 aVersionInfo
.sMinVersion
= OStringToOUString(
199 osVersion
, RTL_TEXTENCODING_UTF8
);
203 sExpresion
= OString("/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"") +
204 osVendor
+ OString("\"]/jf:maxVersion");
205 CXPathObjectPtr xPathObjectMax
;
206 xPathObjectMax
= xmlXPathEvalExpression(
207 (xmlChar
*) sExpresion
.getStr(),
208 m_xmlPathContextVendorSettings
);
209 if (xmlXPathNodeSetIsEmpty(xPathObjectMax
->nodesetval
))
211 aVersionInfo
.sMaxVersion
= OUString();
215 CXmlCharPtr sVersion
;
216 sVersion
= xmlNodeListGetString(
217 m_xmlDocVendorSettings
,
218 xPathObjectMax
->nodesetval
->nodeTab
[0]->xmlChildrenNode
, 1);
219 OString
osVersion((sal_Char
*) (xmlChar
*) sVersion
);
220 aVersionInfo
.sMaxVersion
= OStringToOUString(
221 osVersion
, RTL_TEXTENCODING_UTF8
);
224 //Get excludeVersions
225 sExpresion
= OString("/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"") +
226 osVendor
+ OString("\"]/jf:excludeVersions/jf:version");
227 CXPathObjectPtr xPathObjectVersions
;
228 xPathObjectVersions
=
229 xmlXPathEvalExpression((xmlChar
*) sExpresion
.getStr(),
230 m_xmlPathContextVendorSettings
);
231 if (!xmlXPathNodeSetIsEmpty(xPathObjectVersions
->nodesetval
))
233 xmlNode
* cur
= xPathObjectVersions
->nodesetval
->nodeTab
[0];
236 if (cur
->type
== XML_ELEMENT_NODE
)
238 if (xmlStrcmp(cur
->name
, (xmlChar
*) "version") == 0)
240 CXmlCharPtr sVersion
;
241 sVersion
= xmlNodeListGetString(
242 m_xmlDocVendorSettings
, cur
->xmlChildrenNode
, 1);
243 OString
osVersion((sal_Char
*)(xmlChar
*) sVersion
);
244 OUString usVersion
= OStringToOUString(
245 osVersion
, RTL_TEXTENCODING_UTF8
);
246 aVersionInfo
.addExcludeVersion(usVersion
);
255 std::vector
<OUString
> VendorSettings::getSupportedVendors()
257 std::vector
<OUString
> vecVendors
;
258 //get the nodeset for the library elements
259 jfw::CXPathObjectPtr result
;
260 result
= xmlXPathEvalExpression(
261 (xmlChar
*)"/jf:javaSelection/jf:plugins/jf:library",
262 m_xmlPathContextVendorSettings
);
263 if (xmlXPathNodeSetIsEmpty(result
->nodesetval
))
264 throw FrameworkException(
266 OString("[Java framework] Error in function getSupportedVendors (fwkbase.cxx)."));
268 //get the values of the library elements + vendor attribute
269 xmlNode
* cur
= result
->nodesetval
->nodeTab
[0];
272 //between library elements are also text elements
273 if (cur
->type
== XML_ELEMENT_NODE
)
275 jfw::CXmlCharPtr
sAttrVendor(xmlGetProp(cur
, (xmlChar
*) "vendor"));
276 vecVendors
.push_back(sAttrVendor
);
283 OUString
VendorSettings::getPluginLibrary(const OUString
& sVendor
)
285 OSL_ASSERT(!sVendor
.isEmpty());
287 OString
sExcMsg("[Java framework] Error in function getPluginLibrary (fwkbase.cxx).");
288 OUStringBuffer
usBuffer(256);
289 usBuffer
.appendAscii("/jf:javaSelection/jf:plugins/jf:library[@vendor=\"");
290 usBuffer
.append(sVendor
);
291 usBuffer
.appendAscii("\"]/text()");
292 OUString ouExpr
= usBuffer
.makeStringAndClear();
293 OString sExpression
=
294 OUStringToOString(ouExpr
, osl_getThreadTextEncoding());
295 CXPathObjectPtr pathObjVendor
;
296 pathObjVendor
= xmlXPathEvalExpression(
297 (xmlChar
*) sExpression
.getStr(), m_xmlPathContextVendorSettings
);
298 if (xmlXPathNodeSetIsEmpty(pathObjVendor
->nodesetval
))
299 throw FrameworkException(JFW_E_ERROR
, sExcMsg
);
301 CXmlCharPtr xmlCharPlugin
;
303 xmlNodeListGetString(
304 m_xmlDocVendorSettings
,pathObjVendor
->nodesetval
->nodeTab
[0], 1);
306 //make an absolute file url from the relative plugin URL
307 OUString sUrl
= findPlugin(m_xmlDocVendorSettingsFileUrl
, xmlCharPlugin
);
310 OString sPlugin
= OUStringToOString(
311 xmlCharPlugin
, osl_getThreadTextEncoding());
312 throw FrameworkException(
314 "[Java framework] The file: " + sPlugin
+ " does not exist.");
319 ::std::vector
<OString
> BootParams::getVMParameters()
321 ::std::vector
<OString
> vecParams
;
323 for (sal_Int32 i
= 1; ; i
++)
325 OUString sName
= OUString(UNO_JAVA_JFW_PARAMETER
) + OUString::valueOf(i
);
327 if (Bootstrap::get()->getFrom(sName
, sValue
) == sal_True
)
330 OUStringToOString(sValue
, osl_getThreadTextEncoding());
331 vecParams
.push_back(sParam
);
332 #if OSL_DEBUG_LEVEL >=2
333 OString sParamName
= OUStringToOString(sName
, osl_getThreadTextEncoding());
334 fprintf(stderr
,"[Java framework] Using bootstrap parameter %s"
335 " = %s.\n", sParamName
.getStr(), sParam
.getStr());
344 OUString
BootParams::getUserData()
346 return getParamFirstUrl(UNO_JAVA_JFW_USER_DATA
);
349 OUString
BootParams::getSharedData()
351 return getParamFirstUrl(UNO_JAVA_JFW_SHARED_DATA
);
354 OString
BootParams::getClasspath()
358 if (Bootstrap::get()->getFrom(
359 OUString(UNO_JAVA_JFW_CLASSPATH
),
362 sClassPath
= OUStringToOString(sCP
, osl_getThreadTextEncoding());
363 #if OSL_DEBUG_LEVEL >=2
364 fprintf(stderr
,"[Java framework] Using bootstrap parameter "
365 UNO_JAVA_JFW_CLASSPATH
" = %s.\n", sClassPath
.getStr());
370 if (Bootstrap::get()->getFrom(
371 OUString(UNO_JAVA_JFW_ENV_CLASSPATH
),
374 char * pCp
= getenv("CLASSPATH");
377 char szSep
[] = {SAL_PATHSEPARATOR
,0};
378 sClassPath
+= OString(szSep
) + OString(pCp
);
380 #if OSL_DEBUG_LEVEL >=2
381 fprintf(stderr
,"[Java framework] Using bootstrap parameter "
382 UNO_JAVA_JFW_ENV_CLASSPATH
" and class path is:\n %s.\n", pCp
? pCp
: "");
389 OUString
BootParams::getVendorSettings()
393 UNO_JAVA_JFW_VENDOR_SETTINGS
);
394 if (Bootstrap::get()->getFrom(sName
,sVendor
) == sal_True
)
396 //check the value of the bootstrap variable
397 jfw::FileStatus s
= checkFileURL(sVendor
);
400 //This bootstrap parameter can contain a relative URL
401 OUString sAbsoluteUrl
;
402 OUString sBaseDir
= getLibraryLocation();
403 if (File::getAbsoluteFileURL(sBaseDir
, sVendor
, sAbsoluteUrl
)
405 throw FrameworkException(
407 OString("[Java framework] Invalid value for bootstrap variable: "
408 UNO_JAVA_JFW_VENDOR_SETTINGS
));
409 sVendor
= sAbsoluteUrl
;
410 s
= checkFileURL(sVendor
);
411 if (s
== jfw::FILE_INVALID
|| s
== jfw::FILE_DOES_NOT_EXIST
)
413 throw FrameworkException(
415 OString("[Java framework] Invalid value for bootstrap variable: "
416 UNO_JAVA_JFW_VENDOR_SETTINGS
));
419 #if OSL_DEBUG_LEVEL >=2
420 OString sValue
= OUStringToOString(sVendor
, osl_getThreadTextEncoding());
421 fprintf(stderr
,"[Java framework] Using bootstrap parameter "
422 UNO_JAVA_JFW_VENDOR_SETTINGS
" = %s.\n", sValue
.getStr());
428 OUString
BootParams::getJREHome()
432 sal_Bool bJRE
= Bootstrap::get()->getFrom(
433 OUString(UNO_JAVA_JFW_JREHOME
) ,sJRE
);
434 sal_Bool bEnvJRE
= Bootstrap::get()->getFrom(
435 OUString(UNO_JAVA_JFW_ENV_JREHOME
) ,sEnvJRE
);
437 if (bJRE
== sal_True
&& bEnvJRE
== sal_True
)
439 throw FrameworkException(
441 OString("[Java framework] Both bootstrap parameter "
442 UNO_JAVA_JFW_JREHOME
" and "
443 UNO_JAVA_JFW_ENV_JREHOME
" are set. However only one of them can be set."
444 "Check bootstrap parameters: environment variables, command line "
445 "arguments, rc/ini files for executable and java framework library."));
447 else if (bEnvJRE
== sal_True
)
449 const char * pJRE
= getenv("JAVA_HOME");
452 throw FrameworkException(
454 OString("[Java framework] Both bootstrap parameter "
455 UNO_JAVA_JFW_ENV_JREHOME
" is set, but the environment variable "
456 "JAVA_HOME is not set."));
459 OUString usJRE
= OStringToOUString(osJRE
, osl_getThreadTextEncoding());
460 if (File::getFileURLFromSystemPath(usJRE
, sJRE
) != File::E_None
)
461 throw FrameworkException(
463 OString("[Java framework] Error in function BootParams::getJREHome() "
465 #if OSL_DEBUG_LEVEL >=2
466 fprintf(stderr
,"[Java framework] Using bootstrap parameter "
467 UNO_JAVA_JFW_ENV_JREHOME
" with JAVA_HOME = %s.\n", pJRE
);
470 else if (getMode() == JFW_MODE_DIRECT
471 && bEnvJRE
== sal_False
472 && bJRE
== sal_False
)
474 throw FrameworkException(
476 OString("[Java framework] The bootstrap parameter "
477 UNO_JAVA_JFW_ENV_JREHOME
" or " UNO_JAVA_JFW_JREHOME
478 " must be set in direct mode."));
481 #if OSL_DEBUG_LEVEL >=2
482 if (bJRE
== sal_True
)
484 OString sValue
= OUStringToOString(sJRE
, osl_getThreadTextEncoding());
485 fprintf(stderr
,"[Java framework] Using bootstrap parameter "
486 UNO_JAVA_JFW_JREHOME
" = %s.\n", sValue
.getStr());
492 OUString
BootParams::getClasspathUrls()
495 Bootstrap::get()->getFrom(
496 OUString(UNO_JAVA_JFW_CLASSPATH_URLS
),
498 #if OSL_DEBUG_LEVEL >=2
499 OString sValue
= OUStringToOString(sParams
, osl_getThreadTextEncoding());
500 fprintf(stderr
,"[Java framework] Using bootstrap parameter "
501 UNO_JAVA_JFW_CLASSPATH_URLS
" = %s.\n", sValue
.getStr());
508 static bool g_bMode
= false;
509 static JFW_MODE g_mode
= JFW_MODE_APPLICATION
;
511 if (g_bMode
== false)
513 //check if either of the "direct mode" bootstrap variables is set
514 bool bDirectMode
= true;
516 const rtl::Bootstrap
* aBoot
= Bootstrap::get();
517 OUString
sJREHome(UNO_JAVA_JFW_JREHOME
);
518 if (aBoot
->getFrom(sJREHome
, sValue
) == sal_False
)
520 OUString
sEnvJRE(UNO_JAVA_JFW_ENV_JREHOME
);
521 if (aBoot
->getFrom(sEnvJRE
, sValue
) == sal_False
)
523 OUString
sClasspath(UNO_JAVA_JFW_CLASSPATH
);
524 if (aBoot
->getFrom(sClasspath
, sValue
) == sal_False
)
526 OUString
sEnvClasspath(UNO_JAVA_JFW_ENV_CLASSPATH
);
527 if (aBoot
->getFrom(sEnvClasspath
, sValue
) == sal_False
)
529 OUString sParams
= OUString(
530 UNO_JAVA_JFW_PARAMETER
) +
531 OUString::valueOf((sal_Int32
)1);
532 if (aBoot
->getFrom(sParams
, sValue
) == sal_False
)
542 g_mode
= JFW_MODE_DIRECT
;
544 g_mode
= JFW_MODE_APPLICATION
;
551 OUString
getApplicationClassPath()
553 OSL_ASSERT(getMode() == JFW_MODE_APPLICATION
);
555 OUString sParams
= BootParams::getClasspathUrls();
556 if (sParams
.isEmpty())
561 char szClassPathSep
[] = {SAL_PATHSEPARATOR
,0};
564 OUString
token( sParams
.getToken( 0, ' ', index
).trim() );
565 if (!token
.isEmpty())
567 OUString systemPathElement
;
568 oslFileError rc
= osl_getSystemPathFromFileURL(
569 token
.pData
, &systemPathElement
.pData
);
570 OSL_ASSERT( rc
== osl_File_E_None
);
571 if (rc
== osl_File_E_None
&& !systemPathElement
.isEmpty())
573 if (buf
.getLength() > 0)
574 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(
576 buf
.append( systemPathElement
);
581 return buf
.makeStringAndClear();
584 OString
makeClassPathOption(OUString
const & sUserClassPath
)
586 //Compose the class path
588 OUStringBuffer
sBufCP(4096);
590 // append all user selected jars to the class path
591 if (!sUserClassPath
.isEmpty())
592 sBufCP
.append(sUserClassPath
);
594 //append all jar libraries and components to the class path
595 OUString sAppCP
= getApplicationClassPath();
596 if (!sAppCP
.isEmpty())
598 if (!sUserClassPath
.isEmpty())
600 char szSep
[] = {SAL_PATHSEPARATOR
,0};
601 sBufCP
.appendAscii(szSep
);
603 sBufCP
.append(sAppCP
);
606 sPaths
= OUStringToOString(
607 sBufCP
.makeStringAndClear(), osl_getThreadTextEncoding());
609 OString
sOptionClassPath("-Djava.class.path=");
610 sOptionClassPath
+= sPaths
;
611 return sOptionClassPath
;
614 OString
getUserSettingsPath()
616 return getSettingsPath(BootParams::getUserData());
619 OString
getSharedSettingsPath()
621 return getSettingsPath(BootParams::getSharedData());
624 OString
getSettingsPath( const OUString
& sURL
)
629 if (osl_getSystemPathFromFileURL(sURL
.pData
,
630 & sPath
.pData
) != osl_File_E_None
)
631 throw FrameworkException(
632 JFW_E_ERROR
, OString(
633 "[Java framework] Error in function ::getSettingsPath (fwkbase.cxx)."));
634 return OUStringToOString(sPath
,osl_getThreadTextEncoding());
637 OString
getVendorSettingsPath()
639 return getVendorSettingsPath(BootParams::getVendorSettings());
642 void setJavaSelected()
647 bool wasJavaSelectedInSameProcess()
649 //g_setJavaProcId not set means no Java selected
650 if (g_bJavaSet
== true)
658 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */