tdf#140215 Simplify the handling of .ulf files
[LibreOffice.git] / jvmfwk / source / elements.cxx
blobc48f942ef8e8f4f4ae066a4fd47e804a375c781f
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 <sal/config.h>
21 #include <sal/log.hxx>
23 #include <cassert>
24 #include <memory>
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>
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).
45 using namespace osl;
46 namespace jfw
49 static OString getElement(OString const & docPath,
50 xmlChar const * pathExpression)
52 //Prepare the xml document and context
53 OSL_ASSERT(!docPath.isEmpty());
54 jfw::CXmlDocPtr doc(xmlParseFile(docPath.getStr()));
55 if (doc == nullptr)
56 throw FrameworkException(
57 JFW_E_ERROR,
58 "[Java framework] Error in function getElement (elements.cxx)");
60 jfw::CXPathContextPtr context(xmlXPathNewContext(doc));
61 if (xmlXPathRegisterNs(context, reinterpret_cast<xmlChar const *>("jf"),
62 reinterpret_cast<xmlChar const *>(NS_JAVA_FRAMEWORK)) == -1)
63 throw FrameworkException(
64 JFW_E_ERROR,
65 "[Java framework] Error in function getElement (elements.cxx)");
67 CXPathObjectPtr pathObj = xmlXPathEvalExpression(pathExpression, context);
68 OString sValue;
69 if (xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
71 throw FrameworkException(
72 JFW_E_ERROR,
73 "[Java framework] Error in function getElement (elements.cxx)");
75 sValue = reinterpret_cast<char*>(pathObj->nodesetval->nodeTab[0]->content);
76 return sValue;
79 OString getElementUpdated()
81 return getElement(jfw::getVendorSettingsPath(),
82 reinterpret_cast<xmlChar const *>("/jf:javaSelection/jf:updated/text()"));
85 void createSettingsStructure(xmlDoc * document, bool * bNeedsSave)
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)
96 if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("enabled")) == 0)
98 bFound = true;
99 break;
101 cur = cur->next;
103 if (bFound)
105 *bNeedsSave = false;
106 return;
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));
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);
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);
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);
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);
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);
166 NodeJava::NodeJava(Layer layer):
167 m_layer(layer)
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(
173 JFW_E_DIRECT_MODE,
174 "[Java framework] Trying to access settings files in direct mode.");
178 void NodeJava::load()
180 const OString sExcMsg("[Java framework] Error in function NodeJava::load"
181 "(elements.cxx).");
182 if (SHARED == m_layer)
184 //we do not support yet to write into the shared installation
186 //check if shared settings exist at all.
187 OUString sURL(BootParams::getSharedData());
188 jfw::FileStatus s = sURL.isEmpty()
189 ? FILE_DOES_NOT_EXIST : checkFileURL(sURL);
190 if (s == FILE_INVALID)
191 throw FrameworkException(
192 JFW_E_ERROR,
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;
198 else if (USER == m_layer)
200 if (!prepareSettingsDocument())
202 SAL_INFO("jfw.level1", "no path to load user settings document from");
203 return;
206 else
208 OSL_FAIL("[Java framework] Unknown enum used.");
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);
219 xmlNode * cur = xmlDocGetRootElement(docUser);
220 if (cur == nullptr || cur->children == nullptr)
221 throw FrameworkException(JFW_E_ERROR, sExcMsg);
223 CXmlCharPtr sNil;
224 cur = cur->children;
225 while (cur != nullptr)
227 if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("enabled")) == 0)
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)
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);
244 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("userClassPath")) == 0)
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)
252 CXmlCharPtr sUser(xmlNodeListGetString(
253 docUser, cur->children, 1));
254 m_userClassPath = std::optional<OUString>(OUString(sUser));
257 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("javaInfo")) == 0)
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);
264 if (xmlStrcmp(sNil, reinterpret_cast<xmlChar const *>("false")) == 0)
266 if (! m_javaInfo)
267 m_javaInfo = std::optional<CNodeJavaInfo>(CNodeJavaInfo());
268 m_javaInfo->loadFromNode(docUser, cur);
271 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("vmParameters")) == 0)
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)
279 if ( ! m_vmParameters)
280 m_vmParameters = std::optional<std::vector<OUString> >(
281 std::vector<OUString> ());
283 xmlNode * pOpt = cur->children;
284 while (pOpt != nullptr)
286 if (xmlStrcmp(pOpt->name, reinterpret_cast<xmlChar const *>("param")) == 0)
288 CXmlCharPtr sOpt = xmlNodeListGetString(
289 docUser, pOpt->children, 1);
290 m_vmParameters->push_back(sOpt);
292 pOpt = pOpt->next;
296 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("jreLocations")) == 0)
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)
304 if (! m_JRELocations)
305 m_JRELocations = std::optional<std::vector<OUString> >(
306 std::vector<OUString>());
308 xmlNode * pLoc = cur->children;
309 while (pLoc != nullptr)
311 if (xmlStrcmp(pLoc->name, reinterpret_cast<xmlChar const *>("location")) == 0)
313 CXmlCharPtr sLoc = xmlNodeListGetString(
314 docUser, pLoc->children, 1);
315 m_JRELocations->push_back(sLoc);
317 pLoc = pLoc->next;
321 cur = cur->next;
325 OString NodeJava::getSettingsPath() const
327 OString ret;
328 switch (m_layer)
330 case USER: ret = getUserSettingsPath(); break;
331 case SHARED: ret = getSharedSettingsPath(); break;
332 default:
333 OSL_FAIL("[Java framework] NodeJava::getSettingsPath()");
335 return ret;
338 OUString NodeJava::getSettingsURL() const
340 OUString ret;
341 switch (m_layer)
343 case USER: ret = BootParams::getUserData(); break;
344 case SHARED: ret = BootParams::getSharedData(); break;
345 default:
346 OSL_FAIL("[Java framework] NodeJava::getSettingsURL()");
348 return ret;
351 bool NodeJava::prepareSettingsDocument() const
353 OString sExcMsg(
354 "[Java framework] Error in function prepareSettingsDocument"
355 " (elements.cxx).");
356 if (!createSettingsDocument())
358 return false;
360 OString sSettings = getSettingsPath();
361 CXmlDocPtr doc(xmlParseFile(sSettings.getStr()));
362 if (!doc)
363 throw FrameworkException(JFW_E_ERROR, sExcMsg);
365 bool bNeedsSave = false;
366 createSettingsStructure(doc, & bNeedsSave);
367 if (bNeedsSave)
369 if (xmlSaveFormatFileEnc(
370 sSettings.getStr(), doc,"UTF-8", 1) == -1)
371 throw FrameworkException(JFW_E_ERROR, sExcMsg);
373 return true;
376 void NodeJava::write() const
378 OString sExcMsg("[Java framework] Error in function NodeJava::writeSettings "
379 "(elements.cxx).");
380 CXmlDocPtr docUser;
381 CXPathContextPtr contextUser;
382 CXPathObjectPtr pathObj;
384 if (!prepareSettingsDocument())
386 SAL_INFO("jfw.level1", "no path to write settings document to");
387 return;
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);
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));
406 //set the <enabled> element
407 //The element must exist
408 if (m_enabled)
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);
415 xmlNode * nodeEnabled = pathObj->nodesetval->nodeTab[0];
416 xmlSetNsProp(nodeEnabled,
417 nsXsi,
418 reinterpret_cast<xmlChar const *>("nil"),
419 reinterpret_cast<xmlChar const *>("false"));
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"));
427 //set the <userClassPath> element
428 //The element must exist
429 if (m_userClassPath)
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);
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)));
441 //set <javaInfo> element
442 if (m_javaInfo)
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]);
452 //set <vmParameters> element
453 if (m_vmParameters)
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"));
464 //remove option elements
465 xmlNode* cur = vmParameters->children;
466 while (cur != nullptr)
468 xmlNode* lastNode = cur;
469 cur = cur->next;
470 xmlUnlinkNode(lastNode);
471 xmlFreeNode(lastNode);
473 //add a new line after <vmParameters>
474 if (!m_vmParameters->empty())
476 xmlNode * nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
477 xmlAddChild(vmParameters, nodeCrLf);
480 for (auto const & vmParameter : *m_vmParameters)
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);
490 //set <jreLocations> element
491 if (m_JRELocations)
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"));
502 //remove option elements
503 xmlNode* cur = jreLocationsNode->children;
504 while (cur != nullptr)
506 xmlNode* lastNode = cur;
507 cur = cur->next;
508 xmlUnlinkNode(lastNode);
509 xmlFreeNode(lastNode);
511 //add a new line after <vmParameters>
512 if (!m_JRELocations->empty())
514 xmlNode * nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
515 xmlAddChild(jreLocationsNode, nodeCrLf);
518 for (auto const & JRELocation : *m_JRELocations)
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);
528 if (xmlSaveFormatFile(sSettingsPath.getStr(), docUser, 1) == -1)
529 throw FrameworkException(JFW_E_ERROR, sExcMsg);
532 void NodeJava::setEnabled(bool bEnabled)
534 m_enabled = std::optional<sal_Bool>(bEnabled);
538 void NodeJava::setUserClassPath(const OUString & sClassPath)
540 m_userClassPath = std::optional<OUString>(sClassPath);
543 void NodeJava::setJavaInfo(const JavaInfo * pInfo, bool bAutoSelect)
545 if (!m_javaInfo)
546 m_javaInfo = std::optional<CNodeJavaInfo>(CNodeJavaInfo());
547 m_javaInfo->bAutoSelect = bAutoSelect;
548 m_javaInfo->bNil = false;
550 if (pInfo != nullptr)
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;
559 else
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();
570 void NodeJava::setVmParameters(std::vector<OUString> const & arOptions)
572 m_vmParameters = std::optional<std::vector<OUString> >(arOptions);
575 void NodeJava::addJRELocation(OUString const & sLocation)
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);
587 jfw::FileStatus NodeJava::checkSettingsFileStatus(OUString const & sURL)
589 jfw::FileStatus ret = FILE_DOES_NOT_EXIST;
591 //check the file time
592 ::osl::DirectoryItem item;
593 File::RC rc = ::osl::DirectoryItem::get(sURL, item);
594 if (File::E_None == rc)
596 ::osl::FileStatus stat(osl_FileStatus_Mask_Validate);
597 File::RC rc_stat = item.getFileStatus(stat);
598 if (File::E_None == rc_stat)
600 ret = FILE_OK;
602 else if (File::E_NOENT == rc_stat)
604 ret = FILE_DOES_NOT_EXIST;
606 else
608 ret = FILE_INVALID;
611 else if(File::E_NOENT == rc)
613 ret = FILE_DOES_NOT_EXIST;
615 else
617 ret = FILE_INVALID;
619 return ret;
622 bool NodeJava::createSettingsDocument() const
624 const OUString sURL = getSettingsURL();
625 if (sURL.isEmpty())
627 return false;
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;
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);
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);
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"));
650 if (root == nullptr)
651 throw FrameworkException(JFW_E_ERROR, sExcMsg);
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);
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);
665 if (xmlAddPrevSibling(root, com) == nullptr)
666 throw FrameworkException(JFW_E_ERROR, sExcMsg);
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;
675 CNodeJavaInfo::CNodeJavaInfo() :
676 m_bEmptyNode(false), bNil(true), bAutoSelect(true),
677 nRequirements(0)
681 void CNodeJavaInfo::loadFromNode(xmlDoc * pDoc, xmlNode * pJavaInfo)
683 OString sExcMsg("[Java framework] Error in function NodeJavaInfo::loadFromNode "
684 "(elements.cxx).");
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);
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;
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);
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);
717 xmlNode * cur = pJavaInfo->children;
719 while (cur != nullptr)
721 if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("vendor")) == 0)
723 CXmlCharPtr xmlVendor = xmlNodeListGetString(
724 pDoc, cur->children, 1);
725 if (! xmlVendor)
726 return;
727 sVendor = xmlVendor;
729 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("location")) == 0)
731 CXmlCharPtr xmlLocation = xmlNodeListGetString(
732 pDoc, cur->children, 1);
733 sLocation = xmlLocation;
735 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("version")) == 0)
737 CXmlCharPtr xmlVersion = xmlNodeListGetString(
738 pDoc, cur->children, 1);
739 sVersion = xmlVersion;
741 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("requirements")) == 0)
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
758 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("vendorData")) == 0)
760 CXmlCharPtr xmlData = xmlNodeListGetString(
761 pDoc, cur->children, 1);
762 xmlChar* _data = static_cast<xmlChar*>(xmlData);
763 if (_data)
765 rtl::ByteSequence seq(reinterpret_cast<sal_Int8*>(_data), strlen(reinterpret_cast<char*>(_data)));
766 arVendorData = decodeBase16(seq);
769 cur = cur->next;
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;
783 void CNodeJavaInfo::writeToNode(xmlDoc* pDoc,
784 xmlNode* pJavaInfoNode) const
787 OSL_ASSERT(pJavaInfoNode && pDoc);
788 //write the attribute vendorSettings
790 //javaInfo@vendorUpdate
791 //creates the attribute if necessary
792 OString sUpdated = getElementUpdated();
794 xmlSetProp(pJavaInfoNode, reinterpret_cast<xmlChar const *>("vendorUpdate"),
795 reinterpret_cast<xmlChar const *>(sUpdated.getStr()));
797 //javaInfo@autoSelect
798 xmlSetProp(pJavaInfoNode, reinterpret_cast<xmlChar const *>("autoSelect"),
799 reinterpret_cast<xmlChar const *>(bAutoSelect ? "true" : "false"));
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));
807 xmlSetNsProp(pJavaInfoNode,
808 nsXsi,
809 reinterpret_cast<xmlChar const *>("nil"),
810 reinterpret_cast<xmlChar const *>("false"));
812 //Delete the children of JavaInfo
813 xmlNode* cur = pJavaInfoNode->children;
814 while (cur != nullptr)
816 xmlNode* lastNode = cur;
817 cur = cur->next;
818 xmlUnlinkNode(lastNode);
819 xmlFreeNode(lastNode);
822 //If the JavaInfo was set with an empty value,
823 //then we are done.
824 if (m_bEmptyNode)
825 return;
827 //add a new line after <javaInfo>
828 xmlNode * nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
829 xmlAddChild(pJavaInfoNode, nodeCrLf);
831 //Create the vendor element
832 xmlNewTextChild(pJavaInfoNode, nullptr, reinterpret_cast<xmlChar const *>("vendor"),
833 CXmlCharPtr(sVendor));
834 //add a new line for better readability
835 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
836 xmlAddChild(pJavaInfoNode, nodeCrLf);
838 //Create the location element
839 xmlNewTextChild(pJavaInfoNode, nullptr, reinterpret_cast<xmlChar const *>("location"),
840 CXmlCharPtr(sLocation));
841 //add a new line for better readability
842 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
843 xmlAddChild(pJavaInfoNode, nodeCrLf);
845 //Create the version element
846 xmlNewTextChild(pJavaInfoNode, nullptr, reinterpret_cast<xmlChar const *>("version"),
847 CXmlCharPtr(sVersion));
848 //add a new line for better readability
849 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
850 xmlAddChild(pJavaInfoNode, nodeCrLf);
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);
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);
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);
883 std::unique_ptr<JavaInfo> CNodeJavaInfo::makeJavaInfo() const
885 if (bNil || m_bEmptyNode)
886 return std::unique_ptr<JavaInfo>();
887 return std::unique_ptr<JavaInfo>(
888 new JavaInfo{
889 sVendor, sLocation, sVersion, nRequirements,
890 arVendorData});
894 MergedSettings::MergedSettings():
895 m_bEnabled(false)
897 NodeJava settings(NodeJava::USER);
898 settings.load();
899 NodeJava sharedSettings(NodeJava::SHARED);
900 sharedSettings.load();
901 merge(sharedSettings, settings);
904 MergedSettings::~MergedSettings()
908 void MergedSettings::merge(const NodeJava & share, const NodeJava & user)
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;
917 if (user.getUserClassPath())
918 m_sClassPath = * user.getUserClassPath();
919 else if (share.getUserClassPath())
920 m_sClassPath = * share.getUserClassPath();
922 if (user.getJavaInfo())
923 m_javaInfo = * user.getJavaInfo();
924 else if (share.getJavaInfo())
925 m_javaInfo = * share.getJavaInfo();
927 if (user.getVmParameters())
928 m_vmParams = * user.getVmParameters();
929 else if (share.getVmParameters())
930 m_vmParams = * share.getVmParameters();
932 if (user.getJRELocations())
933 m_JRELocations = * user.getJRELocations();
934 else if (share.getJRELocations())
935 m_JRELocations = * share.getJRELocations();
939 ::std::vector< OString> MergedSettings::getVmParametersUtf8() const
941 ::std::vector< OString> ret;
942 for (auto const & vmParam : m_vmParams)
944 ret.push_back( OUStringToOString(vmParam, RTL_TEXTENCODING_UTF8));
946 return ret;
950 std::unique_ptr<JavaInfo> MergedSettings::createJavaInfo() const
952 return m_javaInfo.makeJavaInfo();
954 #ifdef _WIN32
955 bool MergedSettings::getJavaInfoAttrAutoSelect() const
957 return m_javaInfo.bAutoSelect;
959 #endif
960 void MergedSettings::getVmParametersArray(std::vector<OUString> * parParams)
961 const
963 assert(parParams != nullptr);
964 osl::MutexGuard guard(FwkMutex());
966 *parParams = m_vmParams;
971 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */