sw: lokit: make sure to read annotation html with utf-8
[LibreOffice.git] / jvmfwk / source / elements.cxx
blobaaeabf7afd6daddc01a16a5cd2978275f2a1c88f
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/diagnose.h>
28 #include <osl/mutex.hxx>
29 #include <osl/file.hxx>
30 #include <fwkutil.hxx>
31 #include <fwkbase.hxx>
32 #include "framework.hxx"
33 #include <libxmlutil.hxx>
34 #include <algorithm>
35 #include <libxml/parser.h>
36 #include <libxml/xpath.h>
37 #include <libxml/xpathInternals.h>
38 #include <optional>
39 #include <string.h>
41 // For backwards compatibility, the nRequirements flag word is
42 // read/written as potentially signed hexadecimal number (though that has no
43 // practical relevance given that it has only one flag with value 0x01
44 // defined).
46 using namespace osl;
47 namespace jfw
50 static OString getElement(OString const & docPath,
51 xmlChar const * pathExpression)
53 //Prepare the xml document and context
54 OSL_ASSERT(!docPath.isEmpty());
55 jfw::CXmlDocPtr doc(xmlParseFile(docPath.getStr()));
56 if (doc == nullptr)
57 throw FrameworkException(
58 JFW_E_ERROR,
59 "[Java framework] Error in function getElement (elements.cxx)"_ostr);
61 jfw::CXPathContextPtr context(xmlXPathNewContext(doc));
62 if (xmlXPathRegisterNs(context, reinterpret_cast<xmlChar const *>("jf"),
63 reinterpret_cast<xmlChar const *>(NS_JAVA_FRAMEWORK)) == -1)
64 throw FrameworkException(
65 JFW_E_ERROR,
66 "[Java framework] Error in function getElement (elements.cxx)"_ostr);
68 CXPathObjectPtr pathObj = xmlXPathEvalExpression(pathExpression, context);
69 OString sValue;
70 if (xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
72 throw FrameworkException(
73 JFW_E_ERROR,
74 "[Java framework] Error in function getElement (elements.cxx)"_ostr);
76 sValue = reinterpret_cast<char*>(pathObj->nodesetval->nodeTab[0]->content);
77 return sValue;
80 OString getElementUpdated()
82 return getElement(jfw::getVendorSettingsPath(),
83 reinterpret_cast<xmlChar const *>("/jf:javaSelection/jf:updated/text()"));
86 void createSettingsStructure(xmlDoc * document, bool * bNeedsSave)
88 OString sExcMsg("[Java framework] Error in function createSettingsStructure "
89 "(elements.cxx)."_ostr);
90 xmlNode * root = xmlDocGetRootElement(document);
91 if (root == nullptr)
92 throw FrameworkException(JFW_E_ERROR, sExcMsg);
93 bool bFound = false;
94 xmlNode * cur = root->children;
95 while (cur != nullptr)
97 if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("enabled")) == 0)
99 bFound = true;
100 break;
102 cur = cur->next;
104 if (bFound)
106 *bNeedsSave = false;
107 return;
109 //We will modify this document
110 *bNeedsSave = true;
111 // Now we create the child elements ------------------
112 //Get xsi:nil namespace
113 xmlNs* nsXsi = xmlSearchNsByHref(
114 document, root, reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
116 //<enabled xsi:nil="true"
117 xmlNode * nodeEn = xmlNewTextChild(
118 root, nullptr, reinterpret_cast<xmlChar const *>("enabled"), reinterpret_cast<xmlChar const *>(""));
119 if (nodeEn == nullptr)
120 throw FrameworkException(JFW_E_ERROR, sExcMsg);
121 xmlSetNsProp(nodeEn, nsXsi, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>("true"));
122 //add a new line
123 xmlNode * nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
124 xmlAddChild(root, nodeCrLf);
126 //<userClassPath xsi:nil="true">
127 xmlNode * nodeUs = xmlNewTextChild(
128 root, nullptr, reinterpret_cast<xmlChar const *>("userClassPath"), reinterpret_cast<xmlChar const *>(""));
129 if (nodeUs == nullptr)
130 throw FrameworkException(JFW_E_ERROR, sExcMsg);
131 xmlSetNsProp(nodeUs, nsXsi, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>("true"));
132 //add a new line
133 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
134 xmlAddChild(root, nodeCrLf);
136 //<vmParameters xsi:nil="true">
137 xmlNode * nodeVm = xmlNewTextChild(
138 root, nullptr, reinterpret_cast<xmlChar const *>("vmParameters"), reinterpret_cast<xmlChar const *>(""));
139 if (nodeVm == nullptr)
140 throw FrameworkException(JFW_E_ERROR, sExcMsg);
141 xmlSetNsProp(nodeVm, nsXsi, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>("true"));
142 //add a new line
143 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
144 xmlAddChild(root, nodeCrLf);
146 //<jreLocations xsi:nil="true">
147 xmlNode * nodeJre = xmlNewTextChild(
148 root, nullptr, reinterpret_cast<xmlChar const *>("jreLocations"), reinterpret_cast<xmlChar const *>(""));
149 if (nodeJre == nullptr)
150 throw FrameworkException(JFW_E_ERROR, sExcMsg);
151 xmlSetNsProp(nodeJre, nsXsi, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>("true"));
152 //add a new line
153 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
154 xmlAddChild(root, nodeCrLf);
156 //<javaInfo xsi:nil="true">
157 xmlNode * nodeJava = xmlNewTextChild(
158 root, nullptr, reinterpret_cast<xmlChar const *>("javaInfo"), reinterpret_cast<xmlChar const *>(""));
159 if (nodeJava == nullptr)
160 throw FrameworkException(JFW_E_ERROR, sExcMsg);
161 xmlSetNsProp(nodeJava, nsXsi, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>("true"));
162 //add a new line
163 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
164 xmlAddChild(root, nodeCrLf);
167 NodeJava::NodeJava(Layer layer):
168 m_layer(layer)
170 //This class reads and write to files which should only be done in
171 //application mode
172 if (getMode() == JFW_MODE_DIRECT)
173 throw FrameworkException(
174 JFW_E_DIRECT_MODE,
175 "[Java framework] Trying to access settings files in direct mode."_ostr);
179 void NodeJava::load()
181 static constexpr OString sExcMsg("[Java framework] Error in function NodeJava::load"
182 "(elements.cxx)."_ostr);
183 if (SHARED == m_layer)
185 //we do not support yet to write into the shared installation
187 //check if shared settings exist at all.
188 OUString sURL(BootParams::getSharedData());
189 jfw::FileStatus s = sURL.isEmpty()
190 ? FILE_DOES_NOT_EXIST : checkFileURL(sURL);
191 if (s == FILE_INVALID)
192 throw FrameworkException(
193 JFW_E_ERROR,
194 "[Java framework] Invalid file for shared Java settings."_ostr);
195 else if (s == FILE_DOES_NOT_EXIST)
196 //Writing shared data is not supported yet.
197 return;
199 else if (USER == m_layer)
201 if (!prepareSettingsDocument())
203 SAL_INFO("jfw.level1", "no path to load user settings document from");
204 return;
207 else
209 OSL_FAIL("[Java framework] Unknown enum used.");
213 //Read the user elements
214 OString sSettingsPath = getSettingsPath();
215 //There must not be a share settings file
216 CXmlDocPtr docUser(xmlParseFile(sSettingsPath.getStr()));
217 if (docUser == nullptr)
218 throw FrameworkException(JFW_E_ERROR, sExcMsg);
220 xmlNode * cur = xmlDocGetRootElement(docUser);
221 if (cur == nullptr || cur->children == nullptr)
222 throw FrameworkException(JFW_E_ERROR, sExcMsg);
224 CXmlCharPtr sNil;
225 cur = cur->children;
226 while (cur != nullptr)
228 if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("enabled")) == 0)
230 //only overwrite share settings if xsi:nil="false"
231 sNil = xmlGetNsProp(
232 cur, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
233 if (sNil == nullptr)
234 throw FrameworkException(JFW_E_ERROR, sExcMsg);
235 if (xmlStrcmp(sNil, reinterpret_cast<xmlChar const *>("false")) == 0)
237 CXmlCharPtr sEnabled( xmlNodeListGetString(
238 docUser, cur->children, 1));
239 if (xmlStrcmp(sEnabled, reinterpret_cast<xmlChar const *>("true")) == 0)
240 m_enabled = std::optional<sal_Bool>(true);
241 else if (xmlStrcmp(sEnabled, reinterpret_cast<xmlChar const *>("false")) == 0)
242 m_enabled = std::optional<sal_Bool>(false);
245 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("userClassPath")) == 0)
247 sNil = xmlGetNsProp(
248 cur, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
249 if (sNil == nullptr)
250 throw FrameworkException(JFW_E_ERROR, sExcMsg);
251 if (xmlStrcmp(sNil, reinterpret_cast<xmlChar const *>("false")) == 0)
253 CXmlCharPtr sUser(xmlNodeListGetString(
254 docUser, cur->children, 1));
255 m_userClassPath = std::optional<OUString>(OUString(sUser));
258 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("javaInfo")) == 0)
260 sNil = xmlGetNsProp(
261 cur, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
262 if (sNil == nullptr)
263 throw FrameworkException(JFW_E_ERROR, sExcMsg);
265 if (xmlStrcmp(sNil, reinterpret_cast<xmlChar const *>("false")) == 0)
267 if (! m_javaInfo)
268 m_javaInfo = std::optional<CNodeJavaInfo>(CNodeJavaInfo());
269 m_javaInfo->loadFromNode(docUser, cur);
272 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("vmParameters")) == 0)
274 sNil = xmlGetNsProp(
275 cur, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
276 if (sNil == nullptr)
277 throw FrameworkException(JFW_E_ERROR, sExcMsg);
278 if (xmlStrcmp(sNil, reinterpret_cast<xmlChar const *>("false")) == 0)
280 if ( ! m_vmParameters)
281 m_vmParameters = std::optional<std::vector<OUString> >(
282 std::vector<OUString> ());
284 xmlNode * pOpt = cur->children;
285 while (pOpt != nullptr)
287 if (xmlStrcmp(pOpt->name, reinterpret_cast<xmlChar const *>("param")) == 0)
289 CXmlCharPtr sOpt = xmlNodeListGetString(
290 docUser, pOpt->children, 1);
291 m_vmParameters->push_back(sOpt);
293 pOpt = pOpt->next;
297 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("jreLocations")) == 0)
299 sNil = xmlGetNsProp(
300 cur, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
301 if (sNil == nullptr)
302 throw FrameworkException(JFW_E_ERROR, sExcMsg);
303 if (xmlStrcmp(sNil, reinterpret_cast<xmlChar const *>("false")) == 0)
305 if (! m_JRELocations)
306 m_JRELocations = std::optional<std::vector<OUString> >(
307 std::vector<OUString>());
309 xmlNode * pLoc = cur->children;
310 while (pLoc != nullptr)
312 if (xmlStrcmp(pLoc->name, reinterpret_cast<xmlChar const *>("location")) == 0)
314 CXmlCharPtr sLoc = xmlNodeListGetString(
315 docUser, pLoc->children, 1);
316 m_JRELocations->push_back(sLoc);
318 pLoc = pLoc->next;
322 cur = cur->next;
326 OString NodeJava::getSettingsPath() const
328 OString ret;
329 switch (m_layer)
331 case USER: ret = getUserSettingsPath(); break;
332 case SHARED: ret = getSharedSettingsPath(); break;
333 default:
334 OSL_FAIL("[Java framework] NodeJava::getSettingsPath()");
336 return ret;
339 OUString NodeJava::getSettingsURL() const
341 OUString ret;
342 switch (m_layer)
344 case USER: ret = BootParams::getUserData(); break;
345 case SHARED: ret = BootParams::getSharedData(); break;
346 default:
347 OSL_FAIL("[Java framework] NodeJava::getSettingsURL()");
349 return ret;
352 bool NodeJava::prepareSettingsDocument() const
354 OString sExcMsg(
355 "[Java framework] Error in function prepareSettingsDocument"
356 " (elements.cxx)."_ostr);
357 if (!createSettingsDocument())
359 return false;
361 OString sSettings = getSettingsPath();
362 CXmlDocPtr doc(xmlParseFile(sSettings.getStr()));
363 if (!doc)
364 throw FrameworkException(JFW_E_ERROR, sExcMsg);
366 bool bNeedsSave = false;
367 createSettingsStructure(doc, & bNeedsSave);
368 if (bNeedsSave)
370 if (xmlSaveFormatFileEnc(
371 sSettings.getStr(), doc,"UTF-8", 1) == -1)
372 throw FrameworkException(JFW_E_ERROR, sExcMsg);
374 return true;
377 void NodeJava::write() const
379 OString sExcMsg("[Java framework] Error in function NodeJava::writeSettings "
380 "(elements.cxx)."_ostr);
381 CXmlDocPtr docUser;
382 CXPathContextPtr contextUser;
383 CXPathObjectPtr pathObj;
385 if (!prepareSettingsDocument())
387 SAL_INFO("jfw.level1", "no path to write settings document to");
388 return;
391 //Read the user elements
392 OString sSettingsPath = getSettingsPath();
393 docUser = xmlParseFile(sSettingsPath.getStr());
394 if (docUser == nullptr)
395 throw FrameworkException(JFW_E_ERROR, sExcMsg);
396 contextUser = xmlXPathNewContext(docUser);
397 if (xmlXPathRegisterNs(contextUser, reinterpret_cast<xmlChar const *>("jf"),
398 reinterpret_cast<xmlChar const *>(NS_JAVA_FRAMEWORK)) == -1)
399 throw FrameworkException(JFW_E_ERROR, sExcMsg);
401 xmlNode * root = xmlDocGetRootElement(docUser);
402 //Get xsi:nil namespace
403 xmlNs* nsXsi = xmlSearchNsByHref(docUser,
404 root,
405 reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
407 //set the <enabled> element
408 //The element must exist
409 if (m_enabled)
411 pathObj = xmlXPathEvalExpression(reinterpret_cast<xmlChar const *>("/jf:java/jf:enabled"),
412 contextUser);
413 if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
414 throw FrameworkException(JFW_E_ERROR, sExcMsg);
416 xmlNode * nodeEnabled = pathObj->nodesetval->nodeTab[0];
417 xmlSetNsProp(nodeEnabled,
418 nsXsi,
419 reinterpret_cast<xmlChar const *>("nil"),
420 reinterpret_cast<xmlChar const *>("false"));
422 if (m_enabled == std::optional<sal_Bool>(true))
423 xmlNodeSetContent(nodeEnabled,reinterpret_cast<xmlChar const *>("true"));
424 else
425 xmlNodeSetContent(nodeEnabled,reinterpret_cast<xmlChar const *>("false"));
428 //set the <userClassPath> element
429 //The element must exist
430 if (m_userClassPath)
432 pathObj = xmlXPathEvalExpression(reinterpret_cast<xmlChar const *>("/jf:java/jf:userClassPath"),
433 contextUser);
434 if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
435 throw FrameworkException(JFW_E_ERROR, sExcMsg);
437 xmlNode * nodeEnabled = pathObj->nodesetval->nodeTab[0];
438 xmlSetNsProp(nodeEnabled, nsXsi, reinterpret_cast<xmlChar const *>("nil"),reinterpret_cast<xmlChar const *>("false"));
439 xmlNodeSetContent(nodeEnabled,static_cast<xmlChar*>(CXmlCharPtr(*m_userClassPath)));
442 //set <javaInfo> element
443 if (m_javaInfo)
445 pathObj = xmlXPathEvalExpression(reinterpret_cast<xmlChar const *>("/jf:java/jf:javaInfo"),
446 contextUser);
447 if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
448 throw FrameworkException(JFW_E_ERROR, sExcMsg);
449 m_javaInfo->writeToNode(
450 docUser, pathObj->nodesetval->nodeTab[0]);
453 //set <vmParameters> element
454 if (m_vmParameters)
456 pathObj = xmlXPathEvalExpression(reinterpret_cast<xmlChar const *>("/jf:java/jf:vmParameters"),
457 contextUser);
458 if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
459 throw FrameworkException(JFW_E_ERROR, sExcMsg);
460 xmlNode* vmParameters = pathObj->nodesetval->nodeTab[0];
461 //set xsi:nil = false;
462 xmlSetNsProp(vmParameters, nsXsi,reinterpret_cast<xmlChar const *>("nil"),
463 reinterpret_cast<xmlChar const *>("false"));
465 //remove option elements
466 xmlNode* cur = vmParameters->children;
467 while (cur != nullptr)
469 xmlNode* lastNode = cur;
470 cur = cur->next;
471 xmlUnlinkNode(lastNode);
472 xmlFreeNode(lastNode);
474 //add a new line after <vmParameters>
475 if (!m_vmParameters->empty())
477 xmlNode * nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
478 xmlAddChild(vmParameters, nodeCrLf);
481 for (auto const & vmParameter : *m_vmParameters)
483 xmlNewTextChild(vmParameters, nullptr, reinterpret_cast<xmlChar const *>("param"),
484 CXmlCharPtr(vmParameter));
485 //add a new line
486 xmlNode * nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
487 xmlAddChild(vmParameters, nodeCrLf);
491 //set <jreLocations> element
492 if (m_JRELocations)
494 pathObj = xmlXPathEvalExpression(reinterpret_cast<xmlChar const *>("/jf:java/jf:jreLocations"),
495 contextUser);
496 if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
497 throw FrameworkException(JFW_E_ERROR, sExcMsg);
498 xmlNode* jreLocationsNode = pathObj->nodesetval->nodeTab[0];
499 //set xsi:nil = false;
500 xmlSetNsProp(jreLocationsNode, nsXsi,reinterpret_cast<xmlChar const *>("nil"),
501 reinterpret_cast<xmlChar const *>("false"));
503 //remove option elements
504 xmlNode* cur = jreLocationsNode->children;
505 while (cur != nullptr)
507 xmlNode* lastNode = cur;
508 cur = cur->next;
509 xmlUnlinkNode(lastNode);
510 xmlFreeNode(lastNode);
512 //add a new line after <vmParameters>
513 if (!m_JRELocations->empty())
515 xmlNode * nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
516 xmlAddChild(jreLocationsNode, nodeCrLf);
519 for (auto const & JRELocation : *m_JRELocations)
521 xmlNewTextChild(jreLocationsNode, nullptr, reinterpret_cast<xmlChar const *>("location"),
522 CXmlCharPtr(JRELocation));
523 //add a new line
524 xmlNode * nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
525 xmlAddChild(jreLocationsNode, nodeCrLf);
529 if (xmlSaveFormatFile(sSettingsPath.getStr(), docUser, 1) == -1)
530 throw FrameworkException(JFW_E_ERROR, sExcMsg);
533 void NodeJava::setEnabled(bool bEnabled)
535 m_enabled = std::optional<sal_Bool>(bEnabled);
539 void NodeJava::setUserClassPath(const OUString & sClassPath)
541 m_userClassPath = std::optional<OUString>(sClassPath);
544 void NodeJava::setJavaInfo(const JavaInfo * pInfo, bool bAutoSelect)
546 if (!m_javaInfo)
547 m_javaInfo = std::optional<CNodeJavaInfo>(CNodeJavaInfo());
548 m_javaInfo->bAutoSelect = bAutoSelect;
549 m_javaInfo->bNil = false;
551 if (pInfo != nullptr)
553 m_javaInfo->m_bEmptyNode = false;
554 m_javaInfo->sVendor = pInfo->sVendor;
555 m_javaInfo->sLocation = pInfo->sLocation;
556 m_javaInfo->sVersion = pInfo->sVersion;
557 m_javaInfo->nRequirements = pInfo->nRequirements;
558 m_javaInfo->arVendorData = pInfo->arVendorData;
560 else
562 m_javaInfo->m_bEmptyNode = true;
563 m_javaInfo->sVendor.clear();
564 m_javaInfo->sLocation.clear();
565 m_javaInfo->sVersion.clear();
566 m_javaInfo->nRequirements = 0;
567 m_javaInfo->arVendorData = rtl::ByteSequence();
571 void NodeJava::setVmParameters(std::vector<OUString> const & arOptions)
573 m_vmParameters = std::optional<std::vector<OUString> >(arOptions);
576 void NodeJava::addJRELocation(OUString const & sLocation)
578 if (!m_JRELocations)
579 m_JRELocations = std::optional<std::vector<OUString> >(
580 std::vector<OUString> ());
581 //only add the path if not already present
582 std::vector<OUString>::const_iterator it =
583 std::find(m_JRELocations->begin(), m_JRELocations->end(), sLocation);
584 if (it == m_JRELocations->end())
585 m_JRELocations->push_back(sLocation);
588 jfw::FileStatus NodeJava::checkSettingsFileStatus(OUString const & sURL)
590 jfw::FileStatus ret = FILE_DOES_NOT_EXIST;
592 //check the file time
593 ::osl::DirectoryItem item;
594 File::RC rc = ::osl::DirectoryItem::get(sURL, item);
595 if (File::E_None == rc)
597 ::osl::FileStatus stat(osl_FileStatus_Mask_Validate);
598 File::RC rc_stat = item.getFileStatus(stat);
599 if (File::E_None == rc_stat)
601 ret = FILE_OK;
603 else if (File::E_NOENT == rc_stat)
605 ret = FILE_DOES_NOT_EXIST;
607 else
609 ret = FILE_INVALID;
612 else if(File::E_NOENT == rc)
614 ret = FILE_DOES_NOT_EXIST;
616 else
618 ret = FILE_INVALID;
620 return ret;
623 bool NodeJava::createSettingsDocument() const
625 const OUString sURL = getSettingsURL();
626 if (sURL.isEmpty())
628 return false;
630 //make sure there is a user directory
631 OString sExcMsg("[Java framework] Error in function createSettingsDocument "
632 "(elements.cxx)."_ostr);
633 // check if javasettings.xml already exist
634 if (FILE_OK == checkSettingsFileStatus(sURL))
635 return true;
637 //make sure that the directories are created in case they do not exist
638 FileBase::RC rcFile = Directory::createPath(getDirFromFile(sURL));
639 if (rcFile != FileBase::E_EXIST && rcFile != FileBase::E_None)
640 throw FrameworkException(JFW_E_ERROR, sExcMsg);
642 //javasettings.xml does not exist yet
643 CXmlDocPtr doc(xmlNewDoc(reinterpret_cast<xmlChar const *>("1.0")));
644 if (! doc)
645 throw FrameworkException(JFW_E_ERROR, sExcMsg);
647 //Create the root element and name spaces
648 xmlNodePtr root = xmlNewDocNode(
649 doc, nullptr, reinterpret_cast<xmlChar const *>("java"), reinterpret_cast<xmlChar const *>("\n"));
651 if (root == nullptr)
652 throw FrameworkException(JFW_E_ERROR, sExcMsg);
654 if (xmlNewNs(root, reinterpret_cast<xmlChar const *>(NS_JAVA_FRAMEWORK),nullptr) == nullptr)
655 throw FrameworkException(JFW_E_ERROR, sExcMsg);
656 if (xmlNewNs(root,reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE),reinterpret_cast<xmlChar const *>("xsi")) == nullptr)
657 throw FrameworkException(JFW_E_ERROR, sExcMsg);
658 xmlDocSetRootElement(doc, root);
660 //Create a comment
661 xmlNodePtr com = xmlNewComment(
662 reinterpret_cast<xmlChar const *>("This is a generated file. Do not alter this file!"));
663 if (com == nullptr)
664 throw FrameworkException(JFW_E_ERROR, sExcMsg);
666 if (xmlAddPrevSibling(root, com) == nullptr)
667 throw FrameworkException(JFW_E_ERROR, sExcMsg);
669 const OString path = getSettingsPath();
670 if (xmlSaveFormatFileEnc(path.getStr(), doc,"UTF-8", 1) == -1)
671 throw FrameworkException(JFW_E_ERROR, sExcMsg);
672 return true;
676 CNodeJavaInfo::CNodeJavaInfo() :
677 m_bEmptyNode(false), bNil(true), bAutoSelect(true),
678 nRequirements(0)
682 void CNodeJavaInfo::loadFromNode(xmlDoc * pDoc, xmlNode * pJavaInfo)
684 OString sExcMsg("[Java framework] Error in function NodeJavaInfo::loadFromNode "
685 "(elements.cxx)."_ostr);
687 assert(pJavaInfo && pDoc);
688 if (pJavaInfo->children == nullptr)
689 return;
690 //Get the xsi:nil attribute;
691 CXmlCharPtr sNil = xmlGetNsProp(
692 pJavaInfo, reinterpret_cast<xmlChar const *>("nil"), reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
693 if ( ! sNil)
694 throw FrameworkException(JFW_E_ERROR, sExcMsg);
696 if (xmlStrcmp(sNil, reinterpret_cast<xmlChar const *>("true")) == 0)
697 bNil = true;
698 else if (xmlStrcmp(sNil, reinterpret_cast<xmlChar const *>("false")) == 0)
699 bNil = false;
700 else
701 throw FrameworkException(JFW_E_ERROR, sExcMsg);
702 if (bNil)
703 return;
705 //Get javaInfo@manuallySelected attribute
706 CXmlCharPtr sAutoSelect = xmlGetProp(
707 pJavaInfo, reinterpret_cast<xmlChar const *>("autoSelect"));
708 if ( ! sAutoSelect)
709 throw FrameworkException(JFW_E_ERROR, sExcMsg);
711 if (xmlStrcmp(sAutoSelect, reinterpret_cast<xmlChar const *>("true")) == 0)
712 bAutoSelect = true;
713 else if (xmlStrcmp(sAutoSelect, reinterpret_cast<xmlChar const *>("false")) == 0)
714 bAutoSelect = false;
715 else
716 throw FrameworkException(JFW_E_ERROR, sExcMsg);
718 xmlNode * cur = pJavaInfo->children;
720 while (cur != nullptr)
722 if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("vendor")) == 0)
724 CXmlCharPtr xmlVendor = xmlNodeListGetString(
725 pDoc, cur->children, 1);
726 if (! xmlVendor)
727 return;
728 sVendor = xmlVendor;
730 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("location")) == 0)
732 CXmlCharPtr xmlLocation = xmlNodeListGetString(
733 pDoc, cur->children, 1);
734 sLocation = xmlLocation;
736 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("version")) == 0)
738 CXmlCharPtr xmlVersion = xmlNodeListGetString(
739 pDoc, cur->children, 1);
740 sVersion = xmlVersion;
742 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("requirements")) == 0)
744 CXmlCharPtr xmlRequire = xmlNodeListGetString(
745 pDoc, cur->children, 1);
746 OUString sRequire = xmlRequire;
747 nRequirements = sRequire.toInt64(16);
748 #ifdef MACOSX
749 //javaldx is not used anymore in the mac build. In case the Java
750 //corresponding to the saved settings does not exist anymore the
751 //javavm services will look for an existing Java after creation of
752 //the JVM failed. See stoc/source/javavm/javavm.cxx. Only if
753 //nRequirements does not have the flag JFW_REQUIRE_NEEDRESTART the
754 //jvm of the new selected JRE will be started. Old settings (before
755 //OOo 3.3) still contain the flag which can be safely ignored.
756 nRequirements &= ~JFW_REQUIRE_NEEDRESTART;
757 #endif
759 else if (xmlStrcmp(cur->name, reinterpret_cast<xmlChar const *>("vendorData")) == 0)
761 CXmlCharPtr xmlData = xmlNodeListGetString(
762 pDoc, cur->children, 1);
763 xmlChar* _data = static_cast<xmlChar*>(xmlData);
764 if (_data)
766 rtl::ByteSequence seq(reinterpret_cast<sal_Int8*>(_data), strlen(reinterpret_cast<char*>(_data)));
767 arVendorData = decodeBase16(seq);
770 cur = cur->next;
773 if (sVendor.isEmpty())
774 m_bEmptyNode = true;
775 //Get the javainfo attributes
776 CXmlCharPtr sVendorUpdate = xmlGetProp(pJavaInfo,
777 reinterpret_cast<xmlChar const *>("vendorUpdate"));
778 if ( ! sVendorUpdate)
779 throw FrameworkException(JFW_E_ERROR, sExcMsg);
780 sAttrVendorUpdate = sVendorUpdate;
784 void CNodeJavaInfo::writeToNode(xmlDoc* pDoc,
785 xmlNode* pJavaInfoNode) const
788 assert(pJavaInfoNode && pDoc);
789 //write the attribute vendorSettings
791 //javaInfo@vendorUpdate
792 //creates the attribute if necessary
793 OString sUpdated = getElementUpdated();
795 xmlSetProp(pJavaInfoNode, reinterpret_cast<xmlChar const *>("vendorUpdate"),
796 reinterpret_cast<xmlChar const *>(sUpdated.getStr()));
798 //javaInfo@autoSelect
799 xmlSetProp(pJavaInfoNode, reinterpret_cast<xmlChar const *>("autoSelect"),
800 reinterpret_cast<xmlChar const *>(bAutoSelect ? "true" : "false"));
802 //Set xsi:nil in javaInfo element to false
803 //the xmlNs pointer must not be destroyed
804 xmlNs* nsXsi = xmlSearchNsByHref(pDoc,
805 pJavaInfoNode,
806 reinterpret_cast<xmlChar const *>(NS_SCHEMA_INSTANCE));
808 xmlSetNsProp(pJavaInfoNode,
809 nsXsi,
810 reinterpret_cast<xmlChar const *>("nil"),
811 reinterpret_cast<xmlChar const *>("false"));
813 //Delete the children of JavaInfo
814 xmlNode* cur = pJavaInfoNode->children;
815 while (cur != nullptr)
817 xmlNode* lastNode = cur;
818 cur = cur->next;
819 xmlUnlinkNode(lastNode);
820 xmlFreeNode(lastNode);
823 //If the JavaInfo was set with an empty value,
824 //then we are done.
825 if (m_bEmptyNode)
826 return;
828 //add a new line after <javaInfo>
829 xmlNode * nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
830 xmlAddChild(pJavaInfoNode, nodeCrLf);
832 //Create the vendor element
833 xmlNewTextChild(pJavaInfoNode, nullptr, reinterpret_cast<xmlChar const *>("vendor"),
834 CXmlCharPtr(sVendor));
835 //add a new line for better readability
836 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
837 xmlAddChild(pJavaInfoNode, nodeCrLf);
839 //Create the location element
840 xmlNewTextChild(pJavaInfoNode, nullptr, reinterpret_cast<xmlChar const *>("location"),
841 CXmlCharPtr(sLocation));
842 //add a new line for better readability
843 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
844 xmlAddChild(pJavaInfoNode, nodeCrLf);
846 //Create the version element
847 xmlNewTextChild(pJavaInfoNode, nullptr, reinterpret_cast<xmlChar const *>("version"),
848 CXmlCharPtr(sVersion));
849 //add a new line for better readability
850 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
851 xmlAddChild(pJavaInfoNode, nodeCrLf);
853 //Create the features element, for backwards compatibility (it used to support one flag
854 // JFW_FEATURE_ACCESSBRIDGE = 0x01, but is ignored and always written as zero now)
855 xmlNewTextChild(pJavaInfoNode, nullptr, reinterpret_cast<xmlChar const *>("features"),
856 reinterpret_cast<xmlChar const *>("0"));
857 //add a new line for better readability
858 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
859 xmlAddChild(pJavaInfoNode, nodeCrLf);
862 //Create the requirements element
863 OUString sRequirements = OUString::number(
864 nRequirements, 16);
865 xmlNewTextChild(pJavaInfoNode, nullptr, reinterpret_cast<xmlChar const *>("requirements"),
866 CXmlCharPtr(sRequirements));
867 //add a new line for better readability
868 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
869 xmlAddChild(pJavaInfoNode, nodeCrLf);
872 //Create the vendorData element
873 rtl::ByteSequence data = encodeBase16(arVendorData);
874 xmlNode* dataNode = xmlNewChild(pJavaInfoNode, nullptr,
875 reinterpret_cast<xmlChar const *>("vendorData"),
876 reinterpret_cast<xmlChar const *>(""));
877 xmlNodeSetContentLen(dataNode,
878 reinterpret_cast<xmlChar*>(data.getArray()), data.getLength());
879 //add a new line for better readability
880 nodeCrLf = xmlNewText(reinterpret_cast<xmlChar const *>("\n"));
881 xmlAddChild(pJavaInfoNode, nodeCrLf);
884 std::unique_ptr<JavaInfo> CNodeJavaInfo::makeJavaInfo() const
886 if (bNil || m_bEmptyNode)
887 return std::unique_ptr<JavaInfo>();
888 return std::unique_ptr<JavaInfo>(
889 new JavaInfo{
890 sVendor, sLocation, sVersion, nRequirements,
891 arVendorData});
895 MergedSettings::MergedSettings():
896 m_bEnabled(false)
898 NodeJava settings(NodeJava::USER);
899 settings.load();
900 NodeJava sharedSettings(NodeJava::SHARED);
901 sharedSettings.load();
902 merge(sharedSettings, settings);
905 MergedSettings::~MergedSettings()
909 void MergedSettings::merge(const NodeJava & share, const NodeJava & user)
911 if (user.getEnabled())
912 m_bEnabled = * user.getEnabled();
913 else if (share.getEnabled())
914 m_bEnabled = * share.getEnabled();
915 else
916 m_bEnabled = true;
918 if (user.getUserClassPath())
919 m_sClassPath = * user.getUserClassPath();
920 else if (share.getUserClassPath())
921 m_sClassPath = * share.getUserClassPath();
923 if (user.getJavaInfo())
924 m_javaInfo = * user.getJavaInfo();
925 else if (share.getJavaInfo())
926 m_javaInfo = * share.getJavaInfo();
928 if (user.getVmParameters())
929 m_vmParams = * user.getVmParameters();
930 else if (share.getVmParameters())
931 m_vmParams = * share.getVmParameters();
933 if (user.getJRELocations())
934 m_JRELocations = * user.getJRELocations();
935 else if (share.getJRELocations())
936 m_JRELocations = * share.getJRELocations();
940 ::std::vector< OString> MergedSettings::getVmParametersUtf8() const
942 ::std::vector< OString> ret;
943 for (auto const & vmParam : m_vmParams)
945 ret.push_back( OUStringToOString(vmParam, RTL_TEXTENCODING_UTF8));
947 return ret;
951 std::unique_ptr<JavaInfo> MergedSettings::createJavaInfo() const
953 return m_javaInfo.makeJavaInfo();
955 #ifdef _WIN32
956 bool MergedSettings::getJavaInfoAttrAutoSelect() const
958 return m_javaInfo.bAutoSelect;
960 #endif
961 void MergedSettings::getVmParametersArray(std::vector<OUString> * parParams)
962 const
964 assert(parParams != nullptr);
965 osl::MutexGuard guard(FwkMutex());
967 *parParams = m_vmParams;
972 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */