LibreOffice Module jvmfwk (master) 1
elements.cxx
Go to the documentation of this file.
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 <sal/config.h>
21#include <sal/log.hxx>
22
23#include <cassert>
24#include <memory>
25
26#include <elements.hxx>
27#include <osl/mutex.hxx>
28#include <osl/file.hxx>
29#include <fwkutil.hxx>
30#include <fwkbase.hxx>
31#include "framework.hxx"
32#include <libxmlutil.hxx>
33#include <algorithm>
34#include <libxml/parser.h>
35#include <libxml/xpath.h>
36#include <libxml/xpathInternals.h>
37#include <optional>
38#include <string.h>
39
40// For backwards compatibility, the nRequirements flag word is
41// read/written as potentially signed hexadecimal number (though that has no
42// practical relevance given that it has only one flag with value 0x01
43// defined).
44
45using namespace osl;
46namespace jfw
47{
48
49static OString getElement(OString const & docPath,
50 xmlChar const * pathExpression)
51{
52 //Prepare the xml document and context
53 OSL_ASSERT(!docPath.isEmpty());
54 jfw::CXmlDocPtr doc(xmlParseFile(docPath.getStr()));
55 if (doc == nullptr)
58 "[Java framework] Error in function getElement (elements.cxx)");
59
60 jfw::CXPathContextPtr context(xmlXPathNewContext(doc));
61 if (xmlXPathRegisterNs(context, reinterpret_cast<xmlChar const *>("jf"),
62 reinterpret_cast<xmlChar const *>(NS_JAVA_FRAMEWORK)) == -1)
65 "[Java framework] Error in function getElement (elements.cxx)");
66
67 CXPathObjectPtr pathObj = xmlXPathEvalExpression(pathExpression, context);
68 OString sValue;
69 if (xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
70 {
73 "[Java framework] Error in function getElement (elements.cxx)");
74 }
75 sValue = reinterpret_cast<char*>(pathObj->nodesetval->nodeTab[0]->content);
76 return sValue;
77}
78
80{
82 reinterpret_cast<xmlChar const *>("/jf:javaSelection/jf:updated/text()"));
83}
84
85void createSettingsStructure(xmlDoc * document, bool * bNeedsSave)
86{
87 OString sExcMsg("[Java framework] Error in function createSettingsStructure "
88 "(elements.cxx).");
89 xmlNode * root = xmlDocGetRootElement(document);
90 if (root == nullptr)
91 throw FrameworkException(JFW_E_ERROR, sExcMsg);
92 bool bFound = false;
93 xmlNode * cur = root->children;
94 while (cur != nullptr)
95 {
96 if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("enabled")) == 0)
97 {
98 bFound = true;
99 break;
100 }
101 cur = cur->next;
102 }
103 if (bFound)
104 {
105 *bNeedsSave = false;
106 return;
107 }
108 //We will modify this document
109 *bNeedsSave = true;
110 // Now we create the child elements ------------------
111 //Get xsi:nil namespace
112 xmlNs* nsXsi = xmlSearchNsByHref(
113 document, root, reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
114
115 //<enabled xsi:nil="true"
116 xmlNode * nodeEn = xmlNewTextChild(
117 root, nullptr, reinterpret_cast<xmlChar const *>("enabled"), reinterpret_cast<xmlChar const *>(""));
118 if (nodeEn == nullptr)
119 throw FrameworkException(JFW_E_ERROR, sExcMsg);
120 xmlSetNsProp(nodeEn, nsXsi, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>("true"));
121 //add a new line
122 xmlNode * nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
123 xmlAddChild(root, nodeCrLf);
124
125 //<userClassPath xsi:nil="true">
126 xmlNode * nodeUs = xmlNewTextChild(
127 root, nullptr, reinterpret_cast<xmlChar const *>("userClassPath"), reinterpret_cast<xmlChar const *>(""));
128 if (nodeUs == nullptr)
129 throw FrameworkException(JFW_E_ERROR, sExcMsg);
130 xmlSetNsProp(nodeUs, nsXsi, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>("true"));
131 //add a new line
132 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
133 xmlAddChild(root, nodeCrLf);
134
135 //<vmParameters xsi:nil="true">
136 xmlNode * nodeVm = xmlNewTextChild(
137 root, nullptr, reinterpret_cast<xmlChar const *>("vmParameters"), reinterpret_cast<xmlChar const *>(""));
138 if (nodeVm == nullptr)
139 throw FrameworkException(JFW_E_ERROR, sExcMsg);
140 xmlSetNsProp(nodeVm, nsXsi, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>("true"));
141 //add a new line
142 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
143 xmlAddChild(root, nodeCrLf);
144
145 //<jreLocations xsi:nil="true">
146 xmlNode * nodeJre = xmlNewTextChild(
147 root, nullptr, reinterpret_cast<xmlChar const *>("jreLocations"), reinterpret_cast<xmlChar const *>(""));
148 if (nodeJre == nullptr)
149 throw FrameworkException(JFW_E_ERROR, sExcMsg);
150 xmlSetNsProp(nodeJre, nsXsi, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>("true"));
151 //add a new line
152 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
153 xmlAddChild(root, nodeCrLf);
154
155 //<javaInfo xsi:nil="true">
156 xmlNode * nodeJava = xmlNewTextChild(
157 root, nullptr, reinterpret_cast<xmlChar const *>("javaInfo"), reinterpret_cast<xmlChar const *>(""));
158 if (nodeJava == nullptr)
159 throw FrameworkException(JFW_E_ERROR, sExcMsg);
160 xmlSetNsProp(nodeJava, nsXsi, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>("true"));
161 //add a new line
162 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
163 xmlAddChild(root, nodeCrLf);
164}
165
167 m_layer(layer)
168{
169 //This class reads and write to files which should only be done in
170 //application mode
171 if (getMode() == JFW_MODE_DIRECT)
172 throw FrameworkException(
174 "[Java framework] Trying to access settings files in direct mode.");
175}
176
177
179{
180 static constexpr OStringLiteral sExcMsg("[Java framework] Error in function NodeJava::load"
181 "(elements.cxx).");
182 if (SHARED == m_layer)
183 {
184 //we do not support yet to write into the shared installation
185
186 //check if shared settings exist at all.
187 OUString sURL(BootParams::getSharedData());
188 jfw::FileStatus s = sURL.isEmpty()
190 if (s == FILE_INVALID)
191 throw FrameworkException(
193 "[Java framework] Invalid file for shared Java settings.");
194 else if (s == FILE_DOES_NOT_EXIST)
195 //Writing shared data is not supported yet.
196 return;
197 }
198 else if (USER == m_layer)
199 {
201 {
202 SAL_INFO("jfw.level1", "no path to load user settings document from");
203 return;
204 }
205 }
206 else
207 {
208 OSL_FAIL("[Java framework] Unknown enum used.");
209 }
210
211
212 //Read the user elements
213 OString sSettingsPath = getSettingsPath();
214 //There must not be a share settings file
215 CXmlDocPtr docUser(xmlParseFile(sSettingsPath.getStr()));
216 if (docUser == nullptr)
217 throw FrameworkException(JFW_E_ERROR, sExcMsg);
218
219 xmlNode * cur = xmlDocGetRootElement(docUser);
220 if (cur == nullptr || cur->children == nullptr)
221 throw FrameworkException(JFW_E_ERROR, sExcMsg);
222
223 CXmlCharPtr sNil;
224 cur = cur->children;
225 while (cur != nullptr)
226 {
227 if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("enabled")) == 0)
228 {
229 //only overwrite share settings if xsi:nil="false"
230 sNil = xmlGetNsProp(
231 cur, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
232 if (sNil == nullptr)
233 throw FrameworkException(JFW_E_ERROR, sExcMsg);
234 if (xmlStrcmp(sNil, reinterpret_cast<xmlChar const *>("false")) == 0)
235 {
236 CXmlCharPtr sEnabled( xmlNodeListGetString(
237 docUser, cur->children, 1));
238 if (xmlStrcmp(sEnabled, reinterpret_cast<xmlChar const *>("true")) == 0)
239 m_enabled = std::optional<sal_Bool>(true);
240 else if (xmlStrcmp(sEnabled, reinterpret_cast<xmlChar const *>("false")) == 0)
241 m_enabled = std::optional<sal_Bool>(false);
242 }
243 }
244 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("userClassPath")) == 0)
245 {
246 sNil = xmlGetNsProp(
247 cur, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
248 if (sNil == nullptr)
249 throw FrameworkException(JFW_E_ERROR, sExcMsg);
250 if (xmlStrcmp(sNil, reinterpret_cast<xmlChar const *>("false")) == 0)
251 {
252 CXmlCharPtr sUser(xmlNodeListGetString(
253 docUser, cur->children, 1));
254 m_userClassPath = std::optional<OUString>(OUString(sUser));
255 }
256 }
257 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("javaInfo")) == 0)
258 {
259 sNil = xmlGetNsProp(
260 cur, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
261 if (sNil == nullptr)
262 throw FrameworkException(JFW_E_ERROR, sExcMsg);
263
264 if (xmlStrcmp(sNil, reinterpret_cast<xmlChar const *>("false")) == 0)
265 {
266 if (! m_javaInfo)
267 m_javaInfo = std::optional<CNodeJavaInfo>(CNodeJavaInfo());
268 m_javaInfo->loadFromNode(docUser, cur);
269 }
270 }
271 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("vmParameters")) == 0)
272 {
273 sNil = xmlGetNsProp(
274 cur, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
275 if (sNil == nullptr)
276 throw FrameworkException(JFW_E_ERROR, sExcMsg);
277 if (xmlStrcmp(sNil, reinterpret_cast<xmlChar const *>("false")) == 0)
278 {
279 if ( ! m_vmParameters)
280 m_vmParameters = std::optional<std::vector<OUString> >(
281 std::vector<OUString> ());
282
283 xmlNode * pOpt = cur->children;
284 while (pOpt != nullptr)
285 {
286 if (xmlStrcmp(pOpt->name, reinterpret_cast<xmlChar const *>("param")) == 0)
287 {
288 CXmlCharPtr sOpt = xmlNodeListGetString(
289 docUser, pOpt->children, 1);
290 m_vmParameters->push_back(sOpt);
291 }
292 pOpt = pOpt->next;
293 }
294 }
295 }
296 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("jreLocations")) == 0)
297 {
298 sNil = xmlGetNsProp(
299 cur, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
300 if (sNil == nullptr)
301 throw FrameworkException(JFW_E_ERROR, sExcMsg);
302 if (xmlStrcmp(sNil, reinterpret_cast<xmlChar const *>("false")) == 0)
303 {
304 if (! m_JRELocations)
305 m_JRELocations = std::optional<std::vector<OUString> >(
306 std::vector<OUString>());
307
308 xmlNode * pLoc = cur->children;
309 while (pLoc != nullptr)
310 {
311 if (xmlStrcmp(pLoc->name, reinterpret_cast<xmlChar const *>("location")) == 0)
312 {
313 CXmlCharPtr sLoc = xmlNodeListGetString(
314 docUser, pLoc->children, 1);
315 m_JRELocations->push_back(sLoc);
316 }
317 pLoc = pLoc->next;
318 }
319 }
320 }
321 cur = cur->next;
322 }
323}
324
326{
327 OString ret;
328 switch (m_layer)
329 {
330 case USER: ret = getUserSettingsPath(); break;
331 case SHARED: ret = getSharedSettingsPath(); break;
332 default:
333 OSL_FAIL("[Java framework] NodeJava::getSettingsPath()");
334 }
335 return ret;
336}
337
339{
340 OUString ret;
341 switch (m_layer)
342 {
343 case USER: ret = BootParams::getUserData(); break;
344 case SHARED: ret = BootParams::getSharedData(); break;
345 default:
346 OSL_FAIL("[Java framework] NodeJava::getSettingsURL()");
347 }
348 return ret;
349}
350
352{
353 OString sExcMsg(
354 "[Java framework] Error in function prepareSettingsDocument"
355 " (elements.cxx).");
357 {
358 return false;
359 }
360 OString sSettings = getSettingsPath();
361 CXmlDocPtr doc(xmlParseFile(sSettings.getStr()));
362 if (!doc)
363 throw FrameworkException(JFW_E_ERROR, sExcMsg);
364
365 bool bNeedsSave = false;
366 createSettingsStructure(doc, & bNeedsSave);
367 if (bNeedsSave)
368 {
369 if (xmlSaveFormatFileEnc(
370 sSettings.getStr(), doc,"UTF-8", 1) == -1)
371 throw FrameworkException(JFW_E_ERROR, sExcMsg);
372 }
373 return true;
374}
375
376void NodeJava::write() const
377{
378 OString sExcMsg("[Java framework] Error in function NodeJava::writeSettings "
379 "(elements.cxx).");
380 CXmlDocPtr docUser;
381 CXPathContextPtr contextUser;
382 CXPathObjectPtr pathObj;
383
385 {
386 SAL_INFO("jfw.level1", "no path to write settings document to");
387 return;
388 }
389
390 //Read the user elements
391 OString sSettingsPath = getSettingsPath();
392 docUser = xmlParseFile(sSettingsPath.getStr());
393 if (docUser == nullptr)
394 throw FrameworkException(JFW_E_ERROR, sExcMsg);
395 contextUser = xmlXPathNewContext(docUser);
396 if (xmlXPathRegisterNs(contextUser, reinterpret_cast<xmlChar const *>("jf"),
397 reinterpret_cast<xmlChar const *>(NS_JAVA_FRAMEWORK)) == -1)
398 throw FrameworkException(JFW_E_ERROR, sExcMsg);
399
400 xmlNode * root = xmlDocGetRootElement(docUser);
401 //Get xsi:nil namespace
402 xmlNs* nsXsi = xmlSearchNsByHref(docUser,
403 root,
404 reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
405
406 //set the <enabled> element
407 //The element must exist
408 if (m_enabled)
409 {
410 pathObj = xmlXPathEvalExpression(reinterpret_cast<xmlChar const *>("/jf:java/jf:enabled"),
411 contextUser);
412 if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
413 throw FrameworkException(JFW_E_ERROR, sExcMsg);
414
415 xmlNode * nodeEnabled = pathObj->nodesetval->nodeTab[0];
416 xmlSetNsProp(nodeEnabled,
417 nsXsi,
418 reinterpret_cast<xmlChar const *>("nil"),
419 reinterpret_cast<xmlChar const *>("false"));
420
421 if (m_enabled == std::optional<sal_Bool>(true))
422 xmlNodeSetContent(nodeEnabled,reinterpret_cast<xmlChar const *>("true"));
423 else
424 xmlNodeSetContent(nodeEnabled,reinterpret_cast<xmlChar const *>("false"));
425 }
426
427 //set the <userClassPath> element
428 //The element must exist
429 if (m_userClassPath)
430 {
431 pathObj = xmlXPathEvalExpression(reinterpret_cast<xmlChar const *>("/jf:java/jf:userClassPath"),
432 contextUser);
433 if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
434 throw FrameworkException(JFW_E_ERROR, sExcMsg);
435
436 xmlNode * nodeEnabled = pathObj->nodesetval->nodeTab[0];
437 xmlSetNsProp(nodeEnabled, nsXsi, reinterpret_cast<xmlChar const *>("nil"),reinterpret_cast<xmlChar const *>("false"));
438 xmlNodeSetContent(nodeEnabled,static_cast<xmlChar*>(CXmlCharPtr(*m_userClassPath)));
439 }
440
441 //set <javaInfo> element
442 if (m_javaInfo)
443 {
444 pathObj = xmlXPathEvalExpression(reinterpret_cast<xmlChar const *>("/jf:java/jf:javaInfo"),
445 contextUser);
446 if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
447 throw FrameworkException(JFW_E_ERROR, sExcMsg);
448 m_javaInfo->writeToNode(
449 docUser, pathObj->nodesetval->nodeTab[0]);
450 }
451
452 //set <vmParameters> element
453 if (m_vmParameters)
454 {
455 pathObj = xmlXPathEvalExpression(reinterpret_cast<xmlChar const *>("/jf:java/jf:vmParameters"),
456 contextUser);
457 if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
458 throw FrameworkException(JFW_E_ERROR, sExcMsg);
459 xmlNode* vmParameters = pathObj->nodesetval->nodeTab[0];
460 //set xsi:nil = false;
461 xmlSetNsProp(vmParameters, nsXsi,reinterpret_cast<xmlChar const *>("nil"),
462 reinterpret_cast<xmlChar const *>("false"));
463
464 //remove option elements
465 xmlNode* cur = vmParameters->children;
466 while (cur != nullptr)
467 {
468 xmlNode* lastNode = cur;
469 cur = cur->next;
470 xmlUnlinkNode(lastNode);
471 xmlFreeNode(lastNode);
472 }
473 //add a new line after <vmParameters>
474 if (!m_vmParameters->empty())
475 {
476 xmlNode * nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
477 xmlAddChild(vmParameters, nodeCrLf);
478 }
479
480 for (auto const & vmParameter : *m_vmParameters)
481 {
482 xmlNewTextChild(vmParameters, nullptr, reinterpret_cast<xmlChar const *>("param"),
483 CXmlCharPtr(vmParameter));
484 //add a new line
485 xmlNode * nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
486 xmlAddChild(vmParameters, nodeCrLf);
487 }
488 }
489
490 //set <jreLocations> element
491 if (m_JRELocations)
492 {
493 pathObj = xmlXPathEvalExpression(reinterpret_cast<xmlChar const *>("/jf:java/jf:jreLocations"),
494 contextUser);
495 if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
496 throw FrameworkException(JFW_E_ERROR, sExcMsg);
497 xmlNode* jreLocationsNode = pathObj->nodesetval->nodeTab[0];
498 //set xsi:nil = false;
499 xmlSetNsProp(jreLocationsNode, nsXsi,reinterpret_cast<xmlChar const *>("nil"),
500 reinterpret_cast<xmlChar const *>("false"));
501
502 //remove option elements
503 xmlNode* cur = jreLocationsNode->children;
504 while (cur != nullptr)
505 {
506 xmlNode* lastNode = cur;
507 cur = cur->next;
508 xmlUnlinkNode(lastNode);
509 xmlFreeNode(lastNode);
510 }
511 //add a new line after <vmParameters>
512 if (!m_JRELocations->empty())
513 {
514 xmlNode * nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
515 xmlAddChild(jreLocationsNode, nodeCrLf);
516 }
517
518 for (auto const & JRELocation : *m_JRELocations)
519 {
520 xmlNewTextChild(jreLocationsNode, nullptr, reinterpret_cast<xmlChar const *>("location"),
521 CXmlCharPtr(JRELocation));
522 //add a new line
523 xmlNode * nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
524 xmlAddChild(jreLocationsNode, nodeCrLf);
525 }
526 }
527
528 if (xmlSaveFormatFile(sSettingsPath.getStr(), docUser, 1) == -1)
529 throw FrameworkException(JFW_E_ERROR, sExcMsg);
530}
531
532void NodeJava::setEnabled(bool bEnabled)
533{
534 m_enabled = std::optional<sal_Bool>(bEnabled);
535}
536
537
538void NodeJava::setUserClassPath(const OUString & sClassPath)
539{
540 m_userClassPath = std::optional<OUString>(sClassPath);
541}
542
543void NodeJava::setJavaInfo(const JavaInfo * pInfo, bool bAutoSelect)
544{
545 if (!m_javaInfo)
546 m_javaInfo = std::optional<CNodeJavaInfo>(CNodeJavaInfo());
547 m_javaInfo->bAutoSelect = bAutoSelect;
548 m_javaInfo->bNil = false;
549
550 if (pInfo != nullptr)
551 {
552 m_javaInfo->m_bEmptyNode = false;
553 m_javaInfo->sVendor = pInfo->sVendor;
554 m_javaInfo->sLocation = pInfo->sLocation;
555 m_javaInfo->sVersion = pInfo->sVersion;
556 m_javaInfo->nRequirements = pInfo->nRequirements;
557 m_javaInfo->arVendorData = pInfo->arVendorData;
558 }
559 else
560 {
561 m_javaInfo->m_bEmptyNode = true;
562 m_javaInfo->sVendor.clear();
563 m_javaInfo->sLocation.clear();
564 m_javaInfo->sVersion.clear();
565 m_javaInfo->nRequirements = 0;
566 m_javaInfo->arVendorData = rtl::ByteSequence();
567 }
568}
569
570void NodeJava::setVmParameters(std::vector<OUString> const & arOptions)
571{
572 m_vmParameters = std::optional<std::vector<OUString> >(arOptions);
573}
574
575void NodeJava::addJRELocation(OUString const & sLocation)
576{
577 if (!m_JRELocations)
578 m_JRELocations = std::optional<std::vector<OUString> >(
579 std::vector<OUString> ());
580 //only add the path if not already present
581 std::vector<OUString>::const_iterator it =
582 std::find(m_JRELocations->begin(), m_JRELocations->end(), sLocation);
583 if (it == m_JRELocations->end())
584 m_JRELocations->push_back(sLocation);
585}
586
588{
590
591 //check the file time
592 ::osl::DirectoryItem item;
593 File::RC rc = ::osl::DirectoryItem::get(sURL, item);
594 if (File::E_None == rc)
595 {
596 ::osl::FileStatus stat(osl_FileStatus_Mask_Validate);
597 File::RC rc_stat = item.getFileStatus(stat);
598 if (File::E_None == rc_stat)
599 {
600 ret = FILE_OK;
601 }
602 else if (File::E_NOENT == rc_stat)
603 {
605 }
606 else
607 {
608 ret = FILE_INVALID;
609 }
610 }
611 else if(File::E_NOENT == rc)
612 {
614 }
615 else
616 {
617 ret = FILE_INVALID;
618 }
619 return ret;
620}
621
623{
624 const OUString sURL = getSettingsURL();
625 if (sURL.isEmpty())
626 {
627 return false;
628 }
629 //make sure there is a user directory
630 OString sExcMsg("[Java framework] Error in function createSettingsDocument "
631 "(elements.cxx).");
632 // check if javasettings.xml already exist
633 if (FILE_OK == checkSettingsFileStatus(sURL))
634 return true;
635
636 //make sure that the directories are created in case they do not exist
637 FileBase::RC rcFile = Directory::createPath(getDirFromFile(sURL));
638 if (rcFile != FileBase::E_EXIST && rcFile != FileBase::E_None)
639 throw FrameworkException(JFW_E_ERROR, sExcMsg);
640
641 //javasettings.xml does not exist yet
642 CXmlDocPtr doc(xmlNewDoc(reinterpret_cast<xmlChar const *>("1.0")));
643 if (! doc)
644 throw FrameworkException(JFW_E_ERROR, sExcMsg);
645
646 //Create the root element and name spaces
647 xmlNodePtr root = xmlNewDocNode(
648 doc, nullptr, reinterpret_cast<xmlChar const *>("java"), reinterpret_cast<xmlChar const *>("\n"));
649
650 if (root == nullptr)
651 throw FrameworkException(JFW_E_ERROR, sExcMsg);
652
653 if (xmlNewNs(root, reinterpret_cast<xmlChar const *>(NS_JAVA_FRAMEWORK),nullptr) == nullptr)
654 throw FrameworkException(JFW_E_ERROR, sExcMsg);
655 if (xmlNewNs(root,reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE),reinterpret_cast<xmlChar const *>("xsi")) == nullptr)
656 throw FrameworkException(JFW_E_ERROR, sExcMsg);
657 xmlDocSetRootElement(doc, root);
658
659 //Create a comment
660 xmlNodePtr com = xmlNewComment(
661 reinterpret_cast<xmlChar const *>("This is a generated file. Do not alter this file!"));
662 if (com == nullptr)
663 throw FrameworkException(JFW_E_ERROR, sExcMsg);
664
665 if (xmlAddPrevSibling(root, com) == nullptr)
666 throw FrameworkException(JFW_E_ERROR, sExcMsg);
667
668 const OString path = getSettingsPath();
669 if (xmlSaveFormatFileEnc(path.getStr(), doc,"UTF-8", 1) == -1)
670 throw FrameworkException(JFW_E_ERROR, sExcMsg);
671 return true;
672}
673
674
676 m_bEmptyNode(false), bNil(true), bAutoSelect(true),
677 nRequirements(0)
678{
679}
680
681void CNodeJavaInfo::loadFromNode(xmlDoc * pDoc, xmlNode * pJavaInfo)
682{
683 OString sExcMsg("[Java framework] Error in function NodeJavaInfo::loadFromNode "
684 "(elements.cxx).");
685
686 OSL_ASSERT(pJavaInfo && pDoc);
687 if (pJavaInfo->children == nullptr)
688 return;
689 //Get the xsi:nil attribute;
690 CXmlCharPtr sNil = xmlGetNsProp(
691 pJavaInfo, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
692 if ( ! sNil)
693 throw FrameworkException(JFW_E_ERROR, sExcMsg);
694
695 if (xmlStrcmp(sNil, reinterpret_cast<xmlChar const *>("true")) == 0)
696 bNil = true;
697 else if (xmlStrcmp(sNil, reinterpret_cast<xmlChar const *>("false")) == 0)
698 bNil = false;
699 else
700 throw FrameworkException(JFW_E_ERROR, sExcMsg);
701 if (bNil)
702 return;
703
704 //Get javaInfo@manuallySelected attribute
705 CXmlCharPtr sAutoSelect = xmlGetProp(
706 pJavaInfo, reinterpret_cast<xmlChar const *>("autoSelect"));
707 if ( ! sAutoSelect)
708 throw FrameworkException(JFW_E_ERROR, sExcMsg);
709
710 if (xmlStrcmp(sAutoSelect, reinterpret_cast<xmlChar const *>("true")) == 0)
711 bAutoSelect = true;
712 else if (xmlStrcmp(sAutoSelect, reinterpret_cast<xmlChar const *>("false")) == 0)
713 bAutoSelect = false;
714 else
715 throw FrameworkException(JFW_E_ERROR, sExcMsg);
716
717 xmlNode * cur = pJavaInfo->children;
718
719 while (cur != nullptr)
720 {
721 if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("vendor")) == 0)
722 {
723 CXmlCharPtr xmlVendor = xmlNodeListGetString(
724 pDoc, cur->children, 1);
725 if (! xmlVendor)
726 return;
727 sVendor = xmlVendor;
728 }
729 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("location")) == 0)
730 {
731 CXmlCharPtr xmlLocation = xmlNodeListGetString(
732 pDoc, cur->children, 1);
733 sLocation = xmlLocation;
734 }
735 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("version")) == 0)
736 {
737 CXmlCharPtr xmlVersion = xmlNodeListGetString(
738 pDoc, cur->children, 1);
739 sVersion = xmlVersion;
740 }
741 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("requirements")) == 0)
742 {
743 CXmlCharPtr xmlRequire = xmlNodeListGetString(
744 pDoc, cur->children, 1);
745 OUString sRequire = xmlRequire;
746 nRequirements = sRequire.toInt64(16);
747#ifdef MACOSX
748 //javaldx is not used anymore in the mac build. In case the Java
749 //corresponding to the saved settings does not exist anymore the
750 //javavm services will look for an existing Java after creation of
751 //the JVM failed. See stoc/source/javavm/javavm.cxx. Only if
752 //nRequirements does not have the flag JFW_REQUIRE_NEEDRESTART the
753 //jvm of the new selected JRE will be started. Old settings (before
754 //OOo 3.3) still contain the flag which can be safely ignored.
755 nRequirements &= ~JFW_REQUIRE_NEEDRESTART;
756#endif
757 }
758 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("vendorData")) == 0)
759 {
760 CXmlCharPtr xmlData = xmlNodeListGetString(
761 pDoc, cur->children, 1);
762 xmlChar* _data = static_cast<xmlChar*>(xmlData);
763 if (_data)
764 {
765 rtl::ByteSequence seq(reinterpret_cast<sal_Int8*>(_data), strlen(reinterpret_cast<char*>(_data)));
767 }
768 }
769 cur = cur->next;
770 }
771
772 if (sVendor.isEmpty())
773 m_bEmptyNode = true;
774 //Get the javainfo attributes
775 CXmlCharPtr sVendorUpdate = xmlGetProp(pJavaInfo,
776 reinterpret_cast<xmlChar const *>("vendorUpdate"));
777 if ( ! sVendorUpdate)
778 throw FrameworkException(JFW_E_ERROR, sExcMsg);
779 sAttrVendorUpdate = sVendorUpdate;
780}
781
782
784 xmlNode* pJavaInfoNode) const
785
786{
787 OSL_ASSERT(pJavaInfoNode && pDoc);
788 //write the attribute vendorSettings
789
790 //javaInfo@vendorUpdate
791 //creates the attribute if necessary
792 OString sUpdated = getElementUpdated();
793
794 xmlSetProp(pJavaInfoNode, reinterpret_cast<xmlChar const *>("vendorUpdate"),
795 reinterpret_cast<xmlChar const *>(sUpdated.getStr()));
796
797 //javaInfo@autoSelect
798 xmlSetProp(pJavaInfoNode, reinterpret_cast<xmlChar const *>("autoSelect"),
799 reinterpret_cast<xmlChar const *>(bAutoSelect ? "true" : "false"));
800
801 //Set xsi:nil in javaInfo element to false
802 //the xmlNs pointer must not be destroyed
803 xmlNs* nsXsi = xmlSearchNsByHref(pDoc,
804 pJavaInfoNode,
805 reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
806
807 xmlSetNsProp(pJavaInfoNode,
808 nsXsi,
809 reinterpret_cast<xmlChar const *>("nil"),
810 reinterpret_cast<xmlChar const *>("false"));
811
812 //Delete the children of JavaInfo
813 xmlNode* cur = pJavaInfoNode->children;
814 while (cur != nullptr)
815 {
816 xmlNode* lastNode = cur;
817 cur = cur->next;
818 xmlUnlinkNode(lastNode);
819 xmlFreeNode(lastNode);
820 }
821
822 //If the JavaInfo was set with an empty value,
823 //then we are done.
824 if (m_bEmptyNode)
825 return;
826
827 //add a new line after <javaInfo>
828 xmlNode * nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
829 xmlAddChild(pJavaInfoNode, nodeCrLf);
830
831 //Create the vendor element
832 xmlNewTextChild(pJavaInfoNode, nullptr, reinterpret_cast<xmlChar const *>("vendor"),
834 //add a new line for better readability
835 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
836 xmlAddChild(pJavaInfoNode, nodeCrLf);
837
838 //Create the location element
839 xmlNewTextChild(pJavaInfoNode, nullptr, reinterpret_cast<xmlChar const *>("location"),
841 //add a new line for better readability
842 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
843 xmlAddChild(pJavaInfoNode, nodeCrLf);
844
845 //Create the version element
846 xmlNewTextChild(pJavaInfoNode, nullptr, reinterpret_cast<xmlChar const *>("version"),
848 //add a new line for better readability
849 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
850 xmlAddChild(pJavaInfoNode, nodeCrLf);
851
852 //Create the features element, for backwards compatibility (it used to support one flag
853 // JFW_FEATURE_ACCESSBRIDGE = 0x01, but is ignored and always written as zero now)
854 xmlNewTextChild(pJavaInfoNode, nullptr, reinterpret_cast<xmlChar const *>("features"),
855 reinterpret_cast<xmlChar const *>("0"));
856 //add a new line for better readability
857 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
858 xmlAddChild(pJavaInfoNode, nodeCrLf);
859
860
861 //Create the requirements element
862 OUString sRequirements = OUString::number(
863 nRequirements, 16);
864 xmlNewTextChild(pJavaInfoNode, nullptr, reinterpret_cast<xmlChar const *>("requirements"),
865 CXmlCharPtr(sRequirements));
866 //add a new line for better readability
867 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
868 xmlAddChild(pJavaInfoNode, nodeCrLf);
869
870
871 //Create the vendorData element
872 rtl::ByteSequence data = encodeBase16(arVendorData);
873 xmlNode* dataNode = xmlNewChild(pJavaInfoNode, nullptr,
874 reinterpret_cast<xmlChar const *>("vendorData"),
875 reinterpret_cast<xmlChar const *>(""));
876 xmlNodeSetContentLen(dataNode,
877 reinterpret_cast<xmlChar*>(data.getArray()), data.getLength());
878 //add a new line for better readability
879 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
880 xmlAddChild(pJavaInfoNode, nodeCrLf);
881}
882
883std::unique_ptr<JavaInfo> CNodeJavaInfo::makeJavaInfo() const
884{
885 if (bNil || m_bEmptyNode)
886 return std::unique_ptr<JavaInfo>();
887 return std::unique_ptr<JavaInfo>(
888 new JavaInfo{
890 arVendorData});
891}
892
893
895 m_bEnabled(false)
896{
897 NodeJava settings(NodeJava::USER);
898 settings.load();
899 NodeJava sharedSettings(NodeJava::SHARED);
900 sharedSettings.load();
901 merge(sharedSettings, settings);
902}
903
905{
906}
907
908void MergedSettings::merge(const NodeJava & share, const NodeJava & user)
909{
910 if (user.getEnabled())
911 m_bEnabled = * user.getEnabled();
912 else if (share.getEnabled())
913 m_bEnabled = * share.getEnabled();
914 else
915 m_bEnabled = true;
916
917 if (user.getUserClassPath())
919 else if (share.getUserClassPath())
920 m_sClassPath = * share.getUserClassPath();
921
922 if (user.getJavaInfo())
923 m_javaInfo = * user.getJavaInfo();
924 else if (share.getJavaInfo())
925 m_javaInfo = * share.getJavaInfo();
926
927 if (user.getVmParameters())
928 m_vmParams = * user.getVmParameters();
929 else if (share.getVmParameters())
930 m_vmParams = * share.getVmParameters();
931
932 if (user.getJRELocations())
934 else if (share.getJRELocations())
936}
937
938
939::std::vector< OString> MergedSettings::getVmParametersUtf8() const
940{
941 ::std::vector< OString> ret;
942 for (auto const & vmParam : m_vmParams)
943 {
944 ret.push_back( OUStringToOString(vmParam, RTL_TEXTENCODING_UTF8));
945 }
946 return ret;
947}
948
949
950std::unique_ptr<JavaInfo> MergedSettings::createJavaInfo() const
951{
952 return m_javaInfo.makeJavaInfo();
953}
954#ifdef _WIN32
955bool MergedSettings::getJavaInfoAttrAutoSelect() const
956{
957 return m_javaInfo.bAutoSelect;
958}
959#endif
960void MergedSettings::getVmParametersArray(std::vector<OUString> * parParams)
961 const
962{
963 assert(parParams != nullptr);
964 osl::MutexGuard guard(FwkMutex());
965
966 *parParams = m_vmParams;
967}
968
969}
970
971/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
represents the settings saved in the /java/javaInfo element.
Definition: elements.hxx:56
bool bAutoSelect
contains the value of the /java/javaInfo@autoSelect attribute.
Definition: elements.hxx:80
::rtl::ByteSequence arVendorData
Definition: elements.hxx:85
std::unique_ptr< JavaInfo > makeJavaInfo() const
returns NULL if javaInfo is nil.
Definition: elements.cxx:883
OUString sVersion
Definition: elements.hxx:83
bool bNil
contains the nil value of the /java/javaInfo@xsi:nil attribute.
Definition: elements.hxx:73
OString sAttrVendorUpdate
Contains the value of the <updated> element of the javavendors.xml after loadFromNode was called.
Definition: elements.hxx:69
sal_uInt64 nRequirements
Definition: elements.hxx:84
void writeToNode(xmlDoc *pDoc, xmlNode *pJavaInfo) const
The attribute nil will be set to false.
Definition: elements.cxx:783
bool m_bEmptyNode
if true, then javaInfo is empty.
Definition: elements.hxx:63
OUString sLocation
Definition: elements.hxx:82
void loadFromNode(xmlDoc *pDoc, xmlNode *pJavaInfo)
reads the node /java/javaInfo.
Definition: elements.cxx:681
OUString sVendor
Definition: elements.hxx:81
::std::vector< OUString > m_JRELocations
Definition: elements.hxx:279
::std::vector< OString > getVmParametersUtf8() const
Definition: elements.cxx:939
::std::vector< OUString > m_vmParams
Definition: elements.hxx:277
void merge(const NodeJava &share, const NodeJava &user)
Definition: elements.cxx:908
CNodeJavaInfo m_javaInfo
Definition: elements.hxx:281
OUString m_sClassPath
Definition: elements.hxx:275
std::unique_ptr< JavaInfo > createJavaInfo() const
returns a JavaInfo structure representing the node /java/javaInfo.
Definition: elements.cxx:950
void getVmParametersArray(std::vector< OUString > *parParameters) const
Definition: elements.cxx:960
this class represents the java settings based on a particular settings file.
Definition: elements.hxx:114
const std::optional<::std::vector< OUString > > & getVmParameters() const
returns the parameters from the element /java/vmParameters/param.
Definition: elements.hxx:238
void setUserClassPath(const OUString &sClassPath)
sets m_sUserClassPath.
Definition: elements.cxx:538
const std::optional< CNodeJavaInfo > & getJavaInfo() const
returns the value of the element /java/javaInfo.
Definition: elements.hxx:234
std::optional<::std::vector< OUString > > m_vmParameters
User configurable option.
Definition: elements.hxx:178
Layer m_layer
Determines the layer for which the instance the loads and writes the data.
Definition: elements.hxx:156
const std::optional< sal_Bool > & getEnabled() const
returns the value of the element /java/enabled
Definition: elements.hxx:227
OString getSettingsPath() const
returns the system path to the data file which is to be used.
Definition: elements.cxx:325
bool createSettingsDocument() const
helper function for prepareSettingsDocument.
Definition: elements.cxx:622
OUString getSettingsURL() const
returns the file URL to the data file which is to be used.
Definition: elements.cxx:338
void load()
load the values of the settings file.
Definition: elements.cxx:178
bool prepareSettingsDocument() const
creates settings file and fills it with default values.
Definition: elements.cxx:351
const std::optional< OUString > & getUserClassPath() const
returns the value of the element /java/userClassPath.
Definition: elements.hxx:230
void addJRELocation(OUString const &sLocation)
adds a location to the already existing locations.
Definition: elements.cxx:575
std::optional<::std::vector< OUString > > m_JRELocations
User configurable option.
Definition: elements.hxx:183
static jfw::FileStatus checkSettingsFileStatus(OUString const &sURL)
Verifies if the respective settings file exist.
Definition: elements.cxx:587
void setEnabled(bool bEnabled)
sets m_enabled.
Definition: elements.cxx:532
void write() const
writes the data to user settings.
Definition: elements.cxx:376
void setJavaInfo(const JavaInfo *pInfo, bool bAutoSelect)
sets m_aInfo.
Definition: elements.cxx:543
void setVmParameters(std::vector< OUString > const &arParameters)
sets the /java/vmParameters/param elements.
Definition: elements.cxx:570
std::optional< sal_Bool > m_enabled
User configurable option.
Definition: elements.hxx:162
const std::optional<::std::vector< OUString > > & getJRELocations() const
returns the parameters from the element /java/jreLocations/location.
Definition: elements.hxx:242
NodeJava(Layer theLayer)
Definition: elements.cxx:166
std::optional< OUString > m_userClassPath
User configurable option.
Definition: elements.hxx:168
std::optional< CNodeJavaInfo > m_javaInfo
User configurable option.
Definition: elements.hxx:173
#define NS_JAVA_FRAMEWORK
Definition: elements.hxx:34
#define NS_SCHEMA_INSTANCE
Definition: elements.hxx:35
#define SAL_INFO(area, stream)
OUString getSharedData()
Definition: fwkbase.cxx:239
OUString getUserData()
Definition: fwkbase.cxx:234
Definition: elements.cxx:47
static OString getElement(OString const &docPath, xmlChar const *pathExpression)
Definition: elements.cxx:49
OString getElementUpdated()
gets the value of the updated element from the javavendors.xml.
Definition: elements.cxx:79
osl::Mutex & FwkMutex()
Definition: fwkutil.cxx:65
void createSettingsStructure(xmlDoc *document, bool *bNeedsSave)
create the child elements within the root structure for each platform.
Definition: elements.cxx:85
rtl::ByteSequence encodeBase16(const rtl::ByteSequence &rawData)
Definition: fwkutil.cxx:72
OString getSharedSettingsPath()
Returns the system path of the share settings file.
Definition: fwkbase.cxx:481
JFW_MODE getMode()
Definition: fwkbase.cxx:376
@ JFW_MODE_DIRECT
Definition: fwkbase.hxx:79
OString getVendorSettingsPath()
Definition: fwkbase.cxx:499
OUString getDirFromFile(std::u16string_view usFilePath)
Definition: fwkutil.cxx:139
rtl::ByteSequence decodeBase16(const rtl::ByteSequence &data)
Definition: fwkutil.cxx:100
jfw::FileStatus checkFileURL(const OUString &sURL)
checks if the URL is a file.
Definition: fwkutil.cxx:158
OString getUserSettingsPath()
Get the system path to the javasettings.xml Converts the URL returned from getUserSettingsURL to a Sy...
Definition: fwkbase.cxx:476
FileStatus
Definition: fwkutil.hxx:52
@ FILE_OK
Definition: fwkutil.hxx:53
@ FILE_DOES_NOT_EXIST
Definition: fwkutil.hxx:54
@ FILE_INVALID
Definition: fwkutil.hxx:55
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
an instance of this struct represents an installation of a Java Runtime Environment (JRE).
OUString sVersion
contains the version of this Java distribution.
sal_uInt64 nRequirements
indicates requirements for running the java runtime.
OUString sLocation
contains the file URL to the installation directory.
OUString sVendor
contains the vendor.
rtl::ByteSequence arVendorData
contains data needed for the creation of the java runtime.
signed char sal_Int8