summaryrefslogtreecommitdiff
path: root/jvmfwk/source
diff options
context:
space:
mode:
Diffstat (limited to 'jvmfwk/source')
-rw-r--r--jvmfwk/source/elements.cxx1294
-rw-r--r--jvmfwk/source/elements.hxx422
-rw-r--r--jvmfwk/source/framework.cxx1284
-rw-r--r--jvmfwk/source/framework.hxx130
-rw-r--r--jvmfwk/source/framework.map31
-rw-r--r--jvmfwk/source/fwkbase.cxx726
-rw-r--r--jvmfwk/source/fwkbase.hxx161
-rw-r--r--jvmfwk/source/fwkutil.cxx362
-rw-r--r--jvmfwk/source/fwkutil.hxx137
-rw-r--r--jvmfwk/source/javasettings.xsd54
-rw-r--r--jvmfwk/source/javasettings_template.xml35
-rw-r--r--jvmfwk/source/javasettingsunopkginstall.xml3
-rw-r--r--jvmfwk/source/jvmfwk3rc4
-rw-r--r--jvmfwk/source/libxmlutil.cxx187
-rw-r--r--jvmfwk/source/libxmlutil.hxx113
-rw-r--r--jvmfwk/source/makefile.mk87
-rw-r--r--jvmfwk/source/readme.txt9
17 files changed, 5039 insertions, 0 deletions
diff --git a/jvmfwk/source/elements.cxx b/jvmfwk/source/elements.cxx
new file mode 100644
index 000000000000..6ffb07a5ee0b
--- /dev/null
+++ b/jvmfwk/source/elements.cxx
@@ -0,0 +1,1294 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_jvmfwk.hxx"
+#include "elements.hxx"
+#include "osl/mutex.hxx"
+#include "osl/file.hxx"
+#include "osl/time.h"
+#include "fwkutil.hxx"
+#include "fwkbase.hxx"
+#include "framework.hxx"
+#include "libxmlutil.hxx"
+#include "osl/thread.hxx"
+#include <algorithm>
+#include "libxml/parser.h"
+#include "libxml/xpath.h"
+#include "libxml/xpathInternals.h"
+#include "rtl/bootstrap.hxx"
+#include "boost/optional.hpp"
+#include <string.h>
+
+
+using namespace osl;
+namespace jfw
+{
+
+rtl::OString getElement(::rtl::OString const & docPath,
+ xmlChar const * pathExpression, bool bThrowIfEmpty)
+{
+ //Prepare the xml document and context
+ OSL_ASSERT(docPath.getLength() > 0);
+ jfw::CXmlDocPtr doc(xmlParseFile(docPath.getStr()));
+ if (doc == NULL)
+ throw FrameworkException(
+ JFW_E_ERROR,
+ rtl::OString("[Java framework] Error in function getElement "
+ "(elements.cxx)"));
+
+ jfw::CXPathContextPtr context(xmlXPathNewContext(doc));
+ if (xmlXPathRegisterNs(context, (xmlChar*) "jf",
+ (xmlChar*) NS_JAVA_FRAMEWORK) == -1)
+ throw FrameworkException(
+ JFW_E_ERROR,
+ rtl::OString("[Java framework] Error in function getElement "
+ "(elements.cxx)"));
+
+ CXPathObjectPtr pathObj;
+ pathObj = xmlXPathEvalExpression(pathExpression, context);
+ rtl::OString sValue;
+ if (xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
+ {
+ if (bThrowIfEmpty)
+ throw FrameworkException(
+ JFW_E_ERROR,
+ rtl::OString("[Java framework] Error in function getElement "
+ "(elements.cxx)"));
+ }
+ else
+ {
+ sValue = (sal_Char*) pathObj->nodesetval->nodeTab[0]->content;
+ }
+ return sValue;
+}
+
+rtl::OString getElementUpdated()
+{
+ return getElement(jfw::getVendorSettingsPath(),
+ (xmlChar*)"/jf:javaSelection/jf:updated/text()", true);
+}
+
+// Use only in INSTALL mode !!!
+rtl::OString getElementModified()
+{
+ //The modified element is only written in INSTALL mode.
+ //That is NodeJava::m_layer = INSTALL
+ return getElement(jfw::getInstallSettingsPath(),
+ (xmlChar*)"/jf:java/jf:modified/text()", false);
+}
+
+
+void createSettingsStructure(xmlDoc * document, bool * bNeedsSave)
+{
+ rtl::OString sExcMsg("[Java framework] Error in function createSettingsStructure "
+ "(elements.cxx).");
+ xmlNode * root = xmlDocGetRootElement(document);
+ if (root == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ bool bFound = false;
+ xmlNode * cur = root->children;
+ while (cur != NULL)
+ {
+ if (xmlStrcmp(cur->name, (xmlChar*) "enabled") == 0)
+ {
+ bFound = true;
+ break;
+ }
+ cur = cur->next;
+ }
+ if (bFound)
+ {
+ bNeedsSave = false;
+ return;
+ }
+ //We will modify this document
+ *bNeedsSave = true;
+ // Now we create the child elements ------------------
+ //Get xsi:nil namespace
+ xmlNs* nsXsi = xmlSearchNsByHref(
+ document, root,(xmlChar*) NS_SCHEMA_INSTANCE);
+
+ //<enabled xsi:nil="true"
+ xmlNode * nodeEn = xmlNewTextChild(
+ root,NULL, (xmlChar*) "enabled", (xmlChar*) "");
+ if (nodeEn == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ xmlSetNsProp(nodeEn,nsXsi,(xmlChar*) "nil",(xmlChar*) "true");
+ //add a new line
+ xmlNode * nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(root, nodeCrLf);
+
+ //<userClassPath xsi:nil="true">
+ xmlNode * nodeUs = xmlNewTextChild(
+ root,NULL, (xmlChar*) "userClassPath", (xmlChar*) "");
+ if (nodeUs == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ xmlSetNsProp(nodeUs,nsXsi,(xmlChar*) "nil",(xmlChar*) "true");
+ //add a new line
+ nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(root, nodeCrLf);
+
+ //<vmParameters xsi:nil="true">
+ xmlNode * nodeVm = xmlNewTextChild(
+ root,NULL, (xmlChar*) "vmParameters", (xmlChar*) "");
+ if (nodeVm == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ xmlSetNsProp(nodeVm,nsXsi,(xmlChar*) "nil",(xmlChar*) "true");
+ //add a new line
+ nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(root, nodeCrLf);
+
+ //<jreLocations xsi:nil="true">
+ xmlNode * nodeJre = xmlNewTextChild(
+ root,NULL, (xmlChar*) "jreLocations", (xmlChar*) "");
+ if (nodeJre == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ xmlSetNsProp(nodeJre,nsXsi,(xmlChar*) "nil",(xmlChar*) "true");
+ //add a new line
+ nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(root, nodeCrLf);
+
+ //<javaInfo xsi:nil="true">
+ xmlNode * nodeJava = xmlNewTextChild(
+ root,NULL, (xmlChar*) "javaInfo", (xmlChar*) "");
+ if (nodeJava == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ xmlSetNsProp(nodeJava,nsXsi,(xmlChar*) "nil",(xmlChar*) "true");
+ //add a new line
+ nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(root, nodeCrLf);
+}
+
+
+//====================================================================
+VersionInfo::VersionInfo(): arVersions(NULL)
+{
+}
+
+VersionInfo::~VersionInfo()
+{
+ delete [] arVersions;
+}
+
+void VersionInfo::addExcludeVersion(const rtl::OUString& sVersion)
+{
+ vecExcludeVersions.push_back(sVersion);
+}
+
+rtl_uString** VersionInfo::getExcludeVersions()
+{
+ osl::MutexGuard guard(FwkMutex::get());
+ if (arVersions != NULL)
+ return arVersions;
+
+ arVersions = new rtl_uString*[vecExcludeVersions.size()];
+ int j=0;
+ typedef std::vector<rtl::OUString>::const_iterator it;
+ for (it i = vecExcludeVersions.begin(); i != vecExcludeVersions.end();
+ ++i, ++j)
+ {
+ arVersions[j] = vecExcludeVersions[j].pData;
+ }
+ return arVersions;
+}
+
+sal_Int32 VersionInfo::getExcludeVersionSize()
+{
+ return vecExcludeVersions.size();
+}
+//==================================================================
+
+NodeJava::NodeJava(Layer layer):
+ m_layer(layer)
+{
+ //This class reads and write to files which should only be done in
+ //application mode
+ if (getMode() == JFW_MODE_DIRECT)
+ throw FrameworkException(
+ JFW_E_DIRECT_MODE,
+ "[Java framework] Trying to access settings files in direct mode.");
+
+ if (USER_OR_INSTALL == m_layer)
+ {
+ if (BootParams::getInstallData().getLength() > 0)
+ m_layer = INSTALL;
+ else
+ m_layer = USER;
+ }
+ else
+ {
+ m_layer = layer;
+ }
+}
+
+
+void NodeJava::load()
+{
+ const rtl::OString sExcMsg("[Java framework] Error in function NodeJava::load"
+ "(elements.cxx).");
+ if (SHARED == m_layer)
+ {
+ //we do not support yet to write into the shared installation
+
+ //check if shared settings exist at all.
+ jfw::FileStatus s = checkFileURL(BootParams::getSharedData());
+ if (s == FILE_INVALID)
+ throw FrameworkException(
+ JFW_E_ERROR,
+ "[Java framework] Invalid file for shared Java settings.");
+ else if (s == FILE_DOES_NOT_EXIST)
+ //Writing shared data is not supported yet.
+ return;
+ }
+ else if (USER == m_layer || INSTALL == m_layer)
+ {
+ prepareSettingsDocument();
+ }
+ else
+ {
+ OSL_FAIL("[Java framework] Unknown enum used.");
+ }
+
+
+ //Read the user elements
+ rtl::OString sSettingsPath = getSettingsPath();
+ //There must not be a share settings file
+ CXmlDocPtr docUser(xmlParseFile(sSettingsPath.getStr()));
+ if (docUser == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ xmlNode * cur = xmlDocGetRootElement(docUser);
+ if (cur == NULL || cur->children == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ CXmlCharPtr sNil;
+ cur = cur->children;
+ while (cur != NULL)
+ {
+ if (xmlStrcmp(cur->name, (xmlChar*) "enabled") == 0)
+ {
+ //only overwrite share settings if xsi:nil="false"
+ sNil = xmlGetNsProp(
+ cur, (xmlChar*) "nil", (xmlChar*) NS_SCHEMA_INSTANCE);
+ if (sNil == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);;
+ if (xmlStrcmp(sNil, (xmlChar*) "false") == 0)
+ {
+ CXmlCharPtr sEnabled( xmlNodeListGetString(
+ docUser, cur->children, 1));
+ if (xmlStrcmp(sEnabled, (xmlChar*) "true") == 0)
+ m_enabled = boost::optional<sal_Bool>(sal_True);
+ else if (xmlStrcmp(sEnabled, (xmlChar*) "false") == 0)
+ m_enabled = boost::optional<sal_Bool>(sal_False);
+ }
+ }
+ else if (xmlStrcmp(cur->name, (xmlChar*) "userClassPath") == 0)
+ {
+ sNil = xmlGetNsProp(
+ cur, (xmlChar*) "nil", (xmlChar*) NS_SCHEMA_INSTANCE);
+ if (sNil == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ if (xmlStrcmp(sNil, (xmlChar*) "false") == 0)
+ {
+ CXmlCharPtr sUser(xmlNodeListGetString(
+ docUser, cur->children, 1));
+ m_userClassPath = boost::optional<rtl::OUString>(rtl::OUString(sUser));
+ }
+ }
+ else if (xmlStrcmp(cur->name, (xmlChar*) "javaInfo") == 0)
+ {
+ sNil = xmlGetNsProp(
+ cur, (xmlChar*) "nil", (xmlChar*) NS_SCHEMA_INSTANCE);
+ if (sNil == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ if (xmlStrcmp(sNil, (xmlChar*) "false") == 0)
+ {
+ if (! m_javaInfo)
+ m_javaInfo = boost::optional<CNodeJavaInfo>(CNodeJavaInfo());
+ m_javaInfo->loadFromNode(docUser, cur);
+ }
+ }
+ else if (xmlStrcmp(cur->name, (xmlChar*) "vmParameters") == 0)
+ {
+ sNil = xmlGetNsProp(
+ cur, (xmlChar*) "nil", (xmlChar*) NS_SCHEMA_INSTANCE);
+ if (sNil == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ if (xmlStrcmp(sNil, (xmlChar*) "false") == 0)
+ {
+ if ( ! m_vmParameters)
+ m_vmParameters = boost::optional<std::vector<rtl::OUString> >(
+ std::vector<rtl::OUString> ());
+
+ xmlNode * pOpt = cur->children;
+ while (pOpt != NULL)
+ {
+ if (xmlStrcmp(pOpt->name, (xmlChar*) "param") == 0)
+ {
+ CXmlCharPtr sOpt;
+ sOpt = xmlNodeListGetString(
+ docUser, pOpt->children, 1);
+ m_vmParameters->push_back(sOpt);
+ }
+ pOpt = pOpt->next;
+ }
+ }
+ }
+ else if (xmlStrcmp(cur->name, (xmlChar*) "jreLocations") == 0)
+ {
+ sNil = xmlGetNsProp(
+ cur, (xmlChar*) "nil", (xmlChar*) NS_SCHEMA_INSTANCE);
+ if (sNil == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ if (xmlStrcmp(sNil, (xmlChar*) "false") == 0)
+ {
+ if (! m_JRELocations)
+ m_JRELocations = boost::optional<std::vector<rtl::OUString> >(
+ std::vector<rtl::OUString>());
+
+ xmlNode * pLoc = cur->children;
+ while (pLoc != NULL)
+ {
+ if (xmlStrcmp(pLoc->name, (xmlChar*) "location") == 0)
+ {
+ CXmlCharPtr sLoc;
+ sLoc = xmlNodeListGetString(
+ docUser, pLoc->children, 1);
+ m_JRELocations->push_back(sLoc);
+ }
+ pLoc = pLoc->next;
+ }
+ }
+ }
+ cur = cur->next;
+ }
+}
+
+::rtl::OString NodeJava::getSettingsPath() const
+{
+ ::rtl::OString ret;
+ switch (m_layer)
+ {
+ case USER: ret = getUserSettingsPath(); break;
+ case INSTALL: ret = getInstallSettingsPath(); break;
+ case SHARED: ret = getSharedSettingsPath(); break;
+ default:
+ OSL_FAIL("[Java framework] NodeJava::getSettingsPath()");
+ }
+ return ret;
+}
+
+::rtl::OUString NodeJava::getSettingsURL() const
+{
+ ::rtl::OUString ret;
+ switch (m_layer)
+ {
+ case USER: ret = BootParams::getUserData(); break;
+ case INSTALL: ret = BootParams::getInstallData(); break;
+ case SHARED: ret = BootParams::getSharedData(); break;
+ default:
+ OSL_FAIL("[Java framework] NodeJava::getSettingsURL()");
+ }
+ return ret;
+}
+
+void NodeJava::prepareSettingsDocument() const
+{
+ rtl::OString sExcMsg(
+ "[Java framework] Error in function prepareSettingsDocument"
+ " (elements.cxx).");
+ createSettingsDocument();
+ rtl::OString sSettings = getSettingsPath();
+ CXmlDocPtr doc(xmlParseFile(sSettings.getStr()));
+ if (!doc)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ bool bNeedsSave = false;
+ createSettingsStructure(doc, & bNeedsSave);
+ if (bNeedsSave)
+ {
+ if (xmlSaveFormatFileEnc(
+ sSettings.getStr(), doc,"UTF-8", 1) == -1)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ }
+}
+
+void NodeJava::write() const
+{
+ rtl::OString sExcMsg("[Java framework] Error in function NodeJava::writeSettings "
+ "(elements.cxx).");
+ CXmlDocPtr docUser;
+ CXPathContextPtr contextUser;
+ CXPathObjectPtr pathObj;
+
+ prepareSettingsDocument();
+
+ //Read the user elements
+ rtl::OString sSettingsPath = getSettingsPath();
+ docUser = xmlParseFile(sSettingsPath.getStr());
+ if (docUser == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ contextUser = xmlXPathNewContext(docUser);
+ if (xmlXPathRegisterNs(contextUser, (xmlChar*) "jf",
+ (xmlChar*) NS_JAVA_FRAMEWORK) == -1)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ xmlNode * root = xmlDocGetRootElement(docUser);
+ //Get xsi:nil namespace
+ xmlNs* nsXsi = xmlSearchNsByHref(docUser,
+ root,
+ (xmlChar*) NS_SCHEMA_INSTANCE);
+
+ //set the <enabled> element
+ //The element must exist
+ if (m_enabled)
+ {
+ rtl::OString sExpression= rtl::OString(
+ "/jf:java/jf:enabled");
+ pathObj = xmlXPathEvalExpression((xmlChar*) sExpression.getStr(),
+ contextUser);
+ if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ xmlNode * nodeEnabled = pathObj->nodesetval->nodeTab[0];
+ xmlSetNsProp(nodeEnabled,
+ nsXsi,
+ (xmlChar*) "nil",
+ (xmlChar*) "false");
+
+ if (m_enabled == boost::optional<sal_Bool>(sal_True))
+ xmlNodeSetContent(nodeEnabled,(xmlChar*) "true");
+ else
+ xmlNodeSetContent(nodeEnabled,(xmlChar*) "false");
+ }
+
+ //set the <userClassPath> element
+ //The element must exist
+ if (m_userClassPath)
+ {
+ rtl::OString sExpression= rtl::OString(
+ "/jf:java/jf:userClassPath");
+ pathObj = xmlXPathEvalExpression((xmlChar*) sExpression.getStr(),
+ contextUser);
+ if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ xmlNode * nodeEnabled = pathObj->nodesetval->nodeTab[0];
+ xmlSetNsProp(nodeEnabled, nsXsi, (xmlChar*) "nil",(xmlChar*) "false");
+ xmlNodeSetContent(nodeEnabled,(xmlChar*) CXmlCharPtr(*m_userClassPath));
+ }
+
+ //set <javaInfo> element
+ if (m_javaInfo)
+ {
+ rtl::OString sExpression= rtl::OString(
+ "/jf:java/jf:javaInfo");
+ pathObj = xmlXPathEvalExpression((xmlChar*) sExpression.getStr(),
+ contextUser);
+ if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ m_javaInfo->writeToNode(
+ docUser, pathObj->nodesetval->nodeTab[0]);
+ }
+
+ //set <vmParameters> element
+ if (m_vmParameters)
+ {
+ rtl::OString sExpression= rtl::OString(
+ "/jf:java/jf:vmParameters");
+ pathObj = xmlXPathEvalExpression((xmlChar*) sExpression.getStr(),
+ contextUser);
+ if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ xmlNode* vmParameters = pathObj->nodesetval->nodeTab[0];
+ //set xsi:nil = false;
+ xmlSetNsProp(vmParameters, nsXsi,(xmlChar*) "nil",
+ (xmlChar*) "false");
+
+ //remove option elements
+ xmlNode* cur = vmParameters->children;
+ while (cur != NULL)
+ {
+ xmlNode* lastNode = cur;
+ cur = cur->next;
+ xmlUnlinkNode(lastNode);
+ xmlFreeNode(lastNode);
+ }
+ //add a new line after <vmParameters>
+ if (m_vmParameters->size() > 0)
+ {
+ xmlNode * nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(vmParameters, nodeCrLf);
+ }
+
+ typedef std::vector<rtl::OUString>::const_iterator cit;
+ for (cit i = m_vmParameters->begin(); i != m_vmParameters->end(); ++i)
+ {
+ xmlNewTextChild(vmParameters, NULL, (xmlChar*) "param",
+ CXmlCharPtr(*i));
+ //add a new line
+ xmlNode * nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(vmParameters, nodeCrLf);
+ }
+ }
+
+ //set <jreLocations> element
+ if (m_JRELocations)
+ {
+ rtl::OString sExpression= rtl::OString(
+ "/jf:java/jf:jreLocations");
+ pathObj = xmlXPathEvalExpression((xmlChar*) sExpression.getStr(),
+ contextUser);
+ if ( ! pathObj || xmlXPathNodeSetIsEmpty(pathObj->nodesetval))
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ xmlNode* jreLocationsNode = pathObj->nodesetval->nodeTab[0];
+ //set xsi:nil = false;
+ xmlSetNsProp(jreLocationsNode, nsXsi,(xmlChar*) "nil",
+ (xmlChar*) "false");
+
+ //remove option elements
+ xmlNode* cur = jreLocationsNode->children;
+ while (cur != NULL)
+ {
+ xmlNode* lastNode = cur;
+ cur = cur->next;
+ xmlUnlinkNode(lastNode);
+ xmlFreeNode(lastNode);
+ }
+ //add a new line after <vmParameters>
+ if (m_JRELocations->size() > 0)
+ {
+ xmlNode * nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(jreLocationsNode, nodeCrLf);
+ }
+
+ typedef std::vector<rtl::OUString>::const_iterator cit;
+ for (cit i = m_JRELocations->begin(); i != m_JRELocations->end(); ++i)
+ {
+ xmlNewTextChild(jreLocationsNode, NULL, (xmlChar*) "location",
+ CXmlCharPtr(*i));
+ //add a new line
+ xmlNode * nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(jreLocationsNode, nodeCrLf);
+ }
+ }
+
+ if (INSTALL == m_layer)
+ {
+ //now write the current system time
+ ::TimeValue curTime = {0,0};
+ if (::osl_getSystemTime(& curTime))
+ {
+ rtl::OUString sSeconds =
+ rtl::OUString::valueOf((sal_Int64) curTime.Seconds);
+ xmlNewTextChild(
+ root,NULL, (xmlChar*) "modified", CXmlCharPtr(sSeconds));
+ xmlNode * nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(root, nodeCrLf);
+ }
+ }
+ if (xmlSaveFormatFile(sSettingsPath.getStr(), docUser, 1) == -1)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+}
+
+void NodeJava::setEnabled(sal_Bool bEnabled)
+{
+ m_enabled = boost::optional<sal_Bool>(bEnabled);
+}
+
+
+void NodeJava::setUserClassPath(const rtl::OUString & sClassPath)
+{
+ m_userClassPath = boost::optional<rtl::OUString>(sClassPath);
+}
+
+void NodeJava::setJavaInfo(const JavaInfo * pInfo, bool bAutoSelect)
+{
+ if (!m_javaInfo)
+ m_javaInfo = boost::optional<CNodeJavaInfo>(CNodeJavaInfo());
+ m_javaInfo->bAutoSelect = bAutoSelect;
+ m_javaInfo->bNil = false;
+
+ if (pInfo != NULL)
+ {
+ m_javaInfo->m_bEmptyNode = false;
+ m_javaInfo->sVendor = pInfo->sVendor;
+ m_javaInfo->sLocation = pInfo->sLocation;
+ m_javaInfo->sVersion = pInfo->sVersion;
+ m_javaInfo->nFeatures = pInfo->nFeatures;
+ m_javaInfo->nRequirements = pInfo->nRequirements;
+ m_javaInfo->arVendorData = pInfo->arVendorData;
+ }
+ else
+ {
+ m_javaInfo->m_bEmptyNode = true;
+ rtl::OUString sEmpty;
+ m_javaInfo->sVendor = sEmpty;
+ m_javaInfo->sLocation = sEmpty;
+ m_javaInfo->sVersion = sEmpty;
+ m_javaInfo->nFeatures = 0;
+ m_javaInfo->nRequirements = 0;
+ m_javaInfo->arVendorData = rtl::ByteSequence();
+ }
+}
+
+void NodeJava::setVmParameters(rtl_uString * * arOptions, sal_Int32 size)
+{
+ OSL_ASSERT( !(arOptions == 0 && size != 0));
+ if ( ! m_vmParameters)
+ m_vmParameters = boost::optional<std::vector<rtl::OUString> >(
+ std::vector<rtl::OUString>());
+ m_vmParameters->clear();
+ if (arOptions != NULL)
+ {
+ for (int i = 0; i < size; i++)
+ {
+ const rtl::OUString sOption(static_cast<rtl_uString*>(arOptions[i]));
+ m_vmParameters->push_back(sOption);
+ }
+ }
+}
+
+void NodeJava::setJRELocations(rtl_uString * * arLocations, sal_Int32 size)
+{
+ OSL_ASSERT( !(arLocations == 0 && size != 0));
+ if (! m_JRELocations)
+ m_JRELocations = boost::optional<std::vector<rtl::OUString> > (
+ std::vector<rtl::OUString>());
+ m_JRELocations->clear();
+ if (arLocations != NULL)
+ {
+ for (int i = 0; i < size; i++)
+ {
+ const rtl::OUString & sLocation = static_cast<rtl_uString*>(arLocations[i]);
+
+ //only add the path if not already present
+ std::vector<rtl::OUString>::const_iterator it =
+ std::find(m_JRELocations->begin(), m_JRELocations->end(),
+ sLocation);
+ if (it == m_JRELocations->end())
+ m_JRELocations->push_back(sLocation);
+ }
+ }
+}
+
+void NodeJava::addJRELocation(rtl_uString * sLocation)
+{
+ OSL_ASSERT( sLocation);
+ if (!m_JRELocations)
+ m_JRELocations = boost::optional<std::vector<rtl::OUString> >(
+ std::vector<rtl::OUString> ());
+ //only add the path if not already present
+ std::vector<rtl::OUString>::const_iterator it =
+ std::find(m_JRELocations->begin(), m_JRELocations->end(),
+ rtl::OUString(sLocation));
+ if (it == m_JRELocations->end())
+ m_JRELocations->push_back(rtl::OUString(sLocation));
+}
+
+const boost::optional<sal_Bool> & NodeJava::getEnabled() const
+{
+ return m_enabled;
+}
+
+const boost::optional<std::vector<rtl::OUString> >&
+NodeJava::getJRELocations() const
+{
+ return m_JRELocations;
+}
+
+const boost::optional<rtl::OUString> & NodeJava::getUserClassPath() const
+{
+ return m_userClassPath;
+}
+
+const boost::optional<std::vector<rtl::OUString> > & NodeJava::getVmParameters() const
+{
+ return m_vmParameters;
+}
+
+const boost::optional<CNodeJavaInfo> & NodeJava::getJavaInfo() const
+{
+ return m_javaInfo;
+}
+
+jfw::FileStatus NodeJava::checkSettingsFileStatus() const
+{
+ jfw::FileStatus ret = FILE_DOES_NOT_EXIST;
+
+ const rtl::OUString sURL = getSettingsURL();
+ //check the file time
+ ::osl::DirectoryItem item;
+ File::RC rc = ::osl::DirectoryItem::get(sURL, item);
+ if (File::E_None == rc)
+ {
+ ::osl::FileStatus stat(
+ FileStatusMask_Validate
+ | FileStatusMask_CreationTime
+ | FileStatusMask_ModifyTime);
+ File::RC rc_stat = item.getFileStatus(stat);
+ if (File::E_None == rc_stat)
+ {
+ // This
+ //function may be called multiple times when a java is started.
+ //If the expiretime is too small then we may loop because everytime
+ //the file is deleted and we need to search for a java again.
+ if (INSTALL == m_layer)
+ {
+ //file exists. Check if it is too old
+ //Do not use the creation time. On Windows 2003 server I noticed
+ //that after removing the file and shortly later creating it again
+ //did not change the creation time. That is the newly created file
+ //had the creation time of the former file.
+ ::TimeValue curTime = {0,0};
+ ret = FILE_OK;
+ if (sal_True == ::osl_getSystemTime(& curTime))
+ {
+ //get the modified time recorded in the <modified> element
+ sal_uInt32 modified = getModifiedTime();
+ OSL_ASSERT(modified <= curTime.Seconds);
+ //Only if modified has a valued then NodeJava::write was called,
+ //then the xml structure was filled with data.
+
+ if ( modified && curTime.Seconds - modified >
+ BootParams::getInstallDataExpiration())
+ {
+#if OSL_DEBUG_LEVEL >=2
+ fprintf(stderr, "[Java framework] Settings file is %d seconds old. \n",
+ (int)( curTime.Seconds - modified));
+ rtl::OString s = rtl::OUStringToOString(sURL, osl_getThreadTextEncoding());
+ fprintf(stderr, "[Java framework] Settings file is exspired. Deleting settings file at \n%s\n", s.getStr());
+#endif
+ //delete file
+ File f(sURL);
+ if (File::E_None == f.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Read)
+ && File::E_None == f.setPos(0, 0)
+ && File::E_None == f.setSize(0))
+ ret = FILE_DOES_NOT_EXIST;
+ else
+ ret = FILE_INVALID;
+ }
+ else
+ {
+ ret = FILE_OK;
+ }
+ }
+ else // osl_getSystemTime
+ {
+ ret = FILE_INVALID;
+ }
+ }
+ else // INSTALL == m_layer
+ {
+ ret = FILE_OK;
+ }
+ }
+ else if (File::E_NOENT == rc_stat)
+ {
+ ret = FILE_DOES_NOT_EXIST;
+ }
+ else
+ {
+ ret = FILE_INVALID;
+ }
+ }
+ else if(File::E_NOENT == rc)
+ {
+ ret = FILE_DOES_NOT_EXIST;
+ }
+ else
+ {
+ ret = FILE_INVALID;
+ }
+ return ret;
+}
+
+void NodeJava::createSettingsDocument() const
+{
+ const rtl::OUString sURL = getSettingsURL();
+ //make sure there is a user directory
+ rtl::OString sExcMsg("[Java framework] Error in function createSettingsDocument "
+ "(elements.cxx).");
+ // check if javasettings.xml already exist
+ if (FILE_OK == checkSettingsFileStatus())
+ return;
+
+ //make sure that the directories are created in case they do not exist
+ FileBase::RC rcFile = Directory::createPath(getDirFromFile(sURL));
+ if (rcFile != FileBase::E_EXIST && rcFile != FileBase::E_None)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ //javasettings.xml does not exist yet
+ CXmlDocPtr doc(xmlNewDoc((xmlChar *)"1.0"));
+ if (! doc)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ //Create a comment
+ xmlNewDocComment(
+ doc, (xmlChar *) "This is a generated file. Do not alter this file!");
+
+ //Create the root element and name spaces
+ xmlNodePtr root = xmlNewDocNode(
+ doc, NULL, (xmlChar *) "java", (xmlChar *) "\n");
+
+ if (root == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ if (xmlNewNs(root, (xmlChar *) NS_JAVA_FRAMEWORK,NULL) == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ if (xmlNewNs(root,(xmlChar*) NS_SCHEMA_INSTANCE,(xmlChar*)"xsi") == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ xmlDocSetRootElement(doc, root);
+
+ //Create a comment
+ xmlNodePtr com = xmlNewComment(
+ (xmlChar *) "This is a generated file. Do not alter this file!");
+ if (com == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ if (xmlAddPrevSibling(root, com) == NULL)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ const rtl::OString path = getSettingsPath();
+ if (xmlSaveFormatFileEnc(path.getStr(), doc,"UTF-8", 1) == -1)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+}
+
+//=====================================================================
+CNodeJavaInfo::CNodeJavaInfo() :
+ m_bEmptyNode(false), bNil(true), bAutoSelect(true),
+ nFeatures(0), nRequirements(0)
+{
+}
+
+CNodeJavaInfo::~CNodeJavaInfo()
+{
+}
+
+void CNodeJavaInfo::loadFromNode(xmlDoc * pDoc, xmlNode * pJavaInfo)
+{
+ rtl::OString sExcMsg("[Java framework] Error in function NodeJavaInfo::loadFromNode "
+ "(elements.cxx).");
+
+ OSL_ASSERT(pJavaInfo && pDoc);
+ if (pJavaInfo->children == NULL)
+ return;
+ //Get the xsi:nil attribute;
+ CXmlCharPtr sNil;
+ sNil = xmlGetNsProp(
+ pJavaInfo, (xmlChar*) "nil", (xmlChar*) NS_SCHEMA_INSTANCE);
+ if ( ! sNil)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ if (xmlStrcmp(sNil, (xmlChar*) "true") == 0)
+ bNil = true;
+ else if (xmlStrcmp(sNil, (xmlChar*) "false") == 0)
+ bNil = false;
+ else
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ if (bNil == true)
+ return;
+
+ //Get javaInfo@manuallySelected attribute
+ CXmlCharPtr sAutoSelect;
+ sAutoSelect = xmlGetProp(
+ pJavaInfo, (xmlChar*) "autoSelect");
+ if ( ! sAutoSelect)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ if (xmlStrcmp(sAutoSelect, (xmlChar*) "true") == 0)
+ bAutoSelect = true;
+ else if (xmlStrcmp(sAutoSelect, (xmlChar*) "false") == 0)
+ bAutoSelect = false;
+ else
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ xmlNode * cur = pJavaInfo->children;
+
+ while (cur != NULL)
+ {
+ if (xmlStrcmp(cur->name, (xmlChar*) "vendor") == 0)
+ {
+ CXmlCharPtr xmlVendor;
+ xmlVendor = xmlNodeListGetString(
+ pDoc, cur->children, 1);
+ if (! xmlVendor)
+ return;
+ sVendor = xmlVendor;
+ }
+ else if (xmlStrcmp(cur->name, (xmlChar*) "location") == 0)
+ {
+ CXmlCharPtr xmlLocation;
+ xmlLocation = xmlNodeListGetString(
+ pDoc, cur->children, 1);
+ sLocation = xmlLocation;
+ }
+ else if (xmlStrcmp(cur->name, (xmlChar*) "version") == 0)
+ {
+ CXmlCharPtr xmlVersion;
+ xmlVersion = xmlNodeListGetString(
+ pDoc, cur->children, 1);
+ sVersion = xmlVersion;
+ }
+ else if (xmlStrcmp(cur->name, (xmlChar*) "features")== 0)
+ {
+ CXmlCharPtr xmlFeatures;
+ xmlFeatures = xmlNodeListGetString(
+ pDoc, cur->children, 1);
+ rtl::OUString sFeatures = xmlFeatures;
+ nFeatures = sFeatures.toInt64(16);
+ }
+ else if (xmlStrcmp(cur->name, (xmlChar*) "requirements") == 0)
+ {
+ CXmlCharPtr xmlRequire;
+ xmlRequire = xmlNodeListGetString(
+ pDoc, cur->children, 1);
+ rtl::OUString sRequire = xmlRequire;
+ nRequirements = sRequire.toInt64(16);
+#ifdef MACOSX
+ //javaldx is not used anymore in the mac build. In case the Java
+ //corresponding to the saved settings does not exist anymore the
+ //javavm services will look for an existing Java after creation of
+ //the JVM failed. See stoc/source/javavm/javavm.cxx. Only if
+ //nRequirements does not have the flag JFW_REQUIRE_NEEDRESTART the
+ //jvm of the new selected JRE will be started. Old settings (before
+ //OOo 3.3) still contain the flag which can be safely ignored.
+ nRequirements &= ~JFW_REQUIRE_NEEDRESTART;
+#endif
+ }
+ else if (xmlStrcmp(cur->name, (xmlChar*) "vendorData") == 0)
+ {
+ CXmlCharPtr xmlData;
+ xmlData = xmlNodeListGetString(
+ pDoc, cur->children, 1);
+ xmlChar* _data = (xmlChar*) xmlData;
+ if (_data)
+ {
+ rtl::ByteSequence seq((sal_Int8*) _data, strlen((char*)_data));
+ arVendorData = decodeBase16(seq);
+ }
+ }
+ cur = cur->next;
+ }
+
+ if (sVendor.getLength() == 0)
+ m_bEmptyNode = true;
+ //Get the javainfo attributes
+ CXmlCharPtr sVendorUpdate;
+ sVendorUpdate = xmlGetProp(pJavaInfo,
+ (xmlChar*) "vendorUpdate");
+ if ( ! sVendorUpdate)
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+ sAttrVendorUpdate = sVendorUpdate;
+}
+
+
+void CNodeJavaInfo::writeToNode(xmlDoc* pDoc,
+ xmlNode* pJavaInfoNode) const
+
+{
+ OSL_ASSERT(pJavaInfoNode && pDoc);
+ rtl::OString sExcMsg("[Java framework] Error in function NodeJavaInfo::writeToNode "
+ "(elements.cxx).");
+
+ //write the attribute vendorSettings
+
+ //javaInfo@vendorUpdate
+ //creates the attribute if necessary
+ rtl::OString sUpdated = getElementUpdated();
+
+ xmlSetProp(pJavaInfoNode, (xmlChar*)"vendorUpdate",
+ (xmlChar*) sUpdated.getStr());
+
+ //javaInfo@autoSelect
+ xmlSetProp(pJavaInfoNode, (xmlChar*)"autoSelect",
+ (xmlChar*) (bAutoSelect == true ? "true" : "false"));
+
+ //Set xsi:nil in javaInfo element to false
+ //the xmlNs pointer must not be destroyed
+ xmlNs* nsXsi = xmlSearchNsByHref((xmlDoc*) pDoc,
+ pJavaInfoNode,
+ (xmlChar*) NS_SCHEMA_INSTANCE);
+
+ xmlSetNsProp(pJavaInfoNode,
+ nsXsi,
+ (xmlChar*) "nil",
+ (xmlChar*) "false");
+
+ //Delete the children of JavaInfo
+ xmlNode* cur = pJavaInfoNode->children;
+ while (cur != NULL)
+ {
+ xmlNode* lastNode = cur;
+ cur = cur->next;
+ xmlUnlinkNode(lastNode);
+ xmlFreeNode(lastNode);
+ }
+
+ //If the JavaInfo was set with an empty value,
+ //then we are done.
+ if (m_bEmptyNode)
+ return;
+
+ //add a new line after <javaInfo>
+ xmlNode * nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(pJavaInfoNode, nodeCrLf);
+
+ //Create the vendor element
+ xmlNewTextChild(pJavaInfoNode, NULL, (xmlChar*) "vendor",
+ CXmlCharPtr(sVendor));
+ //add a new line for better readability
+ nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(pJavaInfoNode, nodeCrLf);
+
+ //Create the location element
+ xmlNewTextChild(pJavaInfoNode, NULL, (xmlChar*) "location",
+ CXmlCharPtr(sLocation));
+ //add a new line for better readability
+ nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(pJavaInfoNode, nodeCrLf);
+
+ //Create the version element
+ xmlNewTextChild(pJavaInfoNode, NULL, (xmlChar*) "version",
+ CXmlCharPtr(sVersion));
+ //add a new line for better readability
+ nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(pJavaInfoNode, nodeCrLf);
+
+ //Create the features element
+ rtl::OUString sFeatures = rtl::OUString::valueOf(
+ (sal_Int64)nFeatures, 16);
+ xmlNewTextChild(pJavaInfoNode, NULL, (xmlChar*) "features",
+ CXmlCharPtr(sFeatures));
+ //add a new line for better readability
+ nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(pJavaInfoNode, nodeCrLf);
+
+
+ //Create the requirements element
+ rtl::OUString sRequirements = rtl::OUString::valueOf(
+ (sal_Int64) nRequirements, 16);
+ xmlNewTextChild(pJavaInfoNode, NULL, (xmlChar*) "requirements",
+ CXmlCharPtr(sRequirements));
+ //add a new line for better readability
+ nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(pJavaInfoNode, nodeCrLf);
+
+
+ //Create the features element
+ rtl::ByteSequence data = encodeBase16(arVendorData);
+ xmlNode* dataNode = xmlNewChild(pJavaInfoNode, NULL,
+ (xmlChar*) "vendorData",
+ (xmlChar*) "");
+ xmlNodeSetContentLen(dataNode,
+ (xmlChar*) data.getArray(), data.getLength());
+ //add a new line for better readability
+ nodeCrLf = xmlNewText((xmlChar*) "\n");
+ xmlAddChild(pJavaInfoNode, nodeCrLf);
+}
+
+JavaInfo * CNodeJavaInfo::makeJavaInfo() const
+{
+ if (bNil == true || m_bEmptyNode == true)
+ return NULL;
+ JavaInfo * pInfo = (JavaInfo*) rtl_allocateMemory(sizeof(JavaInfo));
+ if (pInfo == NULL)
+ return NULL;
+ memset(pInfo, 0, sizeof(JavaInfo));
+ pInfo->sVendor = sVendor.pData;
+ rtl_uString_acquire(pInfo->sVendor);
+ pInfo->sLocation = sLocation.pData;
+ rtl_uString_acquire(pInfo->sLocation);
+ pInfo->sVersion = sVersion.pData;
+ rtl_uString_acquire(pInfo->sVersion);
+ pInfo->nFeatures = nFeatures;
+ pInfo->nRequirements = nRequirements;
+ pInfo->arVendorData = arVendorData.getHandle();
+ rtl_byte_sequence_acquire(pInfo->arVendorData);
+ return pInfo;
+}
+
+sal_uInt32 NodeJava::getModifiedTime() const
+{
+ if (m_layer != INSTALL)
+ {
+ OSL_ASSERT(0);
+ return 0;
+ }
+ rtl::OString modTimeSeconds = getElementModified();
+ return (sal_uInt32) modTimeSeconds.toInt64();
+}
+
+//================================================================================
+MergedSettings::MergedSettings():
+ m_bEnabled(sal_False),
+ m_sClassPath(),
+ m_vmParams(),
+ m_JRELocations(),
+ m_javaInfo()
+{
+ NodeJava settings(NodeJava::USER_OR_INSTALL);
+ settings.load();
+
+ //Check if UNO_JAVA_JFW_INSTALL_DATA is set. If so, then we need not use user and
+ //shared data.
+ const ::rtl::OUString sInstall = BootParams::getInstallData();
+
+ if (sInstall.getLength() == 0)
+ {
+ NodeJava sharedSettings(NodeJava::SHARED);
+ sharedSettings.load();
+ merge(sharedSettings, settings);
+ }
+ else
+ {
+ merge(NodeJava(), settings);
+ }
+}
+
+MergedSettings::~MergedSettings()
+{
+}
+
+void MergedSettings::merge(const NodeJava & share, const NodeJava & user)
+{
+ if (user.getEnabled())
+ m_bEnabled = * user.getEnabled();
+ else if (share.getEnabled())
+ m_bEnabled = * share.getEnabled();
+ else
+ m_bEnabled = sal_True;
+
+ if (user.getUserClassPath())
+ m_sClassPath = * user.getUserClassPath();
+ else if (share.getUserClassPath())
+ m_sClassPath = * share.getUserClassPath();
+
+ if (user.getJavaInfo())
+ m_javaInfo = * user.getJavaInfo();
+ else if (share.getJavaInfo())
+ m_javaInfo = * share.getJavaInfo();
+
+ if (user.getVmParameters())
+ m_vmParams = * user.getVmParameters();
+ else if (share.getVmParameters())
+ m_vmParams = * share.getVmParameters();
+
+ if (user.getJRELocations())
+ m_JRELocations = * user.getJRELocations();
+ else if (share.getJRELocations())
+ m_JRELocations = * share.getJRELocations();
+}
+
+sal_Bool MergedSettings::getEnabled() const
+{
+ return m_bEnabled;
+}
+const rtl::OUString& MergedSettings::getUserClassPath() const
+{
+ return m_sClassPath;
+}
+
+::std::vector< ::rtl::OString> MergedSettings::getVmParametersUtf8() const
+{
+ ::std::vector< ::rtl::OString> ret;
+ typedef ::std::vector< ::rtl::OUString>::const_iterator cit;
+ for (cit i = m_vmParams.begin(); i < m_vmParams.end(); i++)
+ {
+ ret.push_back( ::rtl::OUStringToOString(*i, RTL_TEXTENCODING_UTF8));
+ }
+ return ret;
+}
+
+const ::rtl::OString & MergedSettings::getJavaInfoAttrVendorUpdate() const
+{
+ return m_javaInfo.sAttrVendorUpdate;
+}
+
+
+JavaInfo * MergedSettings::createJavaInfo() const
+{
+ return m_javaInfo.makeJavaInfo();
+}
+#ifdef WNT
+bool MergedSettings::getJavaInfoAttrAutoSelect() const
+{
+ return m_javaInfo.bAutoSelect;
+}
+#endif
+void MergedSettings::getVmParametersArray(
+ rtl_uString *** parParams, sal_Int32 * size) const
+{
+ osl::MutexGuard guard(FwkMutex::get());
+ OSL_ASSERT(parParams != NULL && size != NULL);
+
+ *parParams = (rtl_uString **)
+ rtl_allocateMemory(sizeof(rtl_uString*) * m_vmParams.size());
+ if (*parParams == NULL)
+ return;
+
+ int j=0;
+ typedef std::vector<rtl::OUString>::const_iterator it;
+ for (it i = m_vmParams.begin(); i != m_vmParams.end();
+ ++i, ++j)
+ {
+ (*parParams)[j] = i->pData;
+ rtl_uString_acquire(i->pData);
+ }
+ *size = m_vmParams.size();
+}
+
+void MergedSettings::getJRELocations(
+ rtl_uString *** parLocations, sal_Int32 * size) const
+{
+ osl::MutexGuard guard(FwkMutex::get());
+ OSL_ASSERT(parLocations != NULL && size != NULL);
+
+ *parLocations = (rtl_uString **)
+ rtl_allocateMemory(sizeof(rtl_uString*) * m_JRELocations.size());
+ if (*parLocations == NULL)
+ return;
+
+ int j=0;
+ typedef std::vector<rtl::OUString>::const_iterator it;
+ for (it i = m_JRELocations.begin(); i != m_JRELocations.end();
+ ++i, ++j)
+ {
+ (*parLocations)[j] = i->pData;
+ rtl_uString_acquire(i->pData);
+ }
+ *size = m_JRELocations.size();
+}
+const std::vector<rtl::OUString> & MergedSettings::getJRELocations() const
+{
+ return m_JRELocations;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/jvmfwk/source/elements.hxx b/jvmfwk/source/elements.hxx
new file mode 100644
index 000000000000..6efedbf96647
--- /dev/null
+++ b/jvmfwk/source/elements.hxx
@@ -0,0 +1,422 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#if !defined INCLUDED_JVMFWK_ELEMENTS_HXX
+#define INCLUDED_JVMFWK_ELEMENTS_HXX
+
+#include <vector>
+#include "jvmfwk/framework.h"
+#include "fwkutil.hxx"
+#include "rtl/ustring.hxx"
+#include "rtl/byteseq.hxx"
+#include "libxml/parser.h"
+#include "boost/optional.hpp"
+
+#define NS_JAVA_FRAMEWORK "http://openoffice.org/2004/java/framework/1.0"
+#define NS_SCHEMA_INSTANCE "http://www.w3.org/2001/XMLSchema-instance"
+
+namespace jfw
+{
+
+/** gets the value of the updated element from the javavendors.xml.
+ */
+rtl::OString getElementUpdated();
+
+/** create the child elements within the root structure for each platform.
+
+ @param bNeedsSave
+ [out]If true then the respective structure of elements was added and the
+ document needs to be saved.
+ */
+void createSettingsStructure(
+ xmlDoc * document, bool * bNeedsSave);
+
+
+/** represents the settings saved in the /java/javaInfo element.
+ It is used within class NodeJava which determines the settings
+ file.
+*/
+class CNodeJavaInfo
+{
+public:
+ CNodeJavaInfo();
+ ~CNodeJavaInfo();
+
+ /** if true, then javaInfo is empty. When writeToNode is called
+ then all child elements are deleted.
+ */
+ bool m_bEmptyNode;
+ /** Contains the value of the <updated> element of
+ the javavendors.xml after loadFromNode was called.
+ It is not used, when the javaInfo node is written.
+ see writeToNode
+ */
+ ::rtl::OString sAttrVendorUpdate;
+ /** contains the nil value of the /java/javaInfo@xsi:nil attribute.
+ Default is true;
+ */
+ bool bNil;
+ /** contains the value of the /java/javaInfo@autoSelect attribute.
+ Default is true. If it is false then the user has modified the JRE
+ selection by actively choosing a JRE from the options dialog. That is,
+ the function jfw_setSelectedJRE was called. Contrary, the function
+ jfw_findAndSelectJRE sets the attribute to true.
+ */
+ bool bAutoSelect;
+ ::rtl::OUString sVendor;
+ ::rtl::OUString sLocation;
+ ::rtl::OUString sVersion;
+ sal_uInt64 nFeatures;
+ sal_uInt64 nRequirements;
+ ::rtl::ByteSequence arVendorData;
+
+ /** reads the node /java/javaInfo.
+ If javaInfo@xsi:nil = true then member bNil is set to true
+ an no further elements are read.
+ */
+ void loadFromNode(xmlDoc * pDoc,xmlNode * pJavaInfo);
+ /** The attribut nil will be set to false. The function gets the value
+ javaSettings/updated from the javavendors.xml and writes it to
+ javaInfo@vendorUpdate in javasettings.xml
+ */
+ void writeToNode(xmlDoc * pDoc, xmlNode * pJavaInfo) const;
+
+ /** returns NULL if javaInfo is nil.
+ */
+ JavaInfo * makeJavaInfo() const;
+};
+
+/** this class represents the java settings based on a particular
+ settings file.
+
+ Which settings file is used is determined by the value passed into the
+ constructo and the values of the bootstrap parameters UNO_JAVA_JFW_USER_DATA,
+ UNO_JAVA_JFW_SHARED_DATA,_JAVA_JFW_INSTALL_DATA.
+
+ If the value is USER_OR_INSTALL then it depends of the bootstrap parameter
+ UNO_JAVA_JFW_INSTALL_DATA. If it has as value then it is used. Otherwise the
+ value from UNO_JAVA_JFW_USER_DATA is used.
+
+ The method load reads the data from the settings file.
+ The method write stores the data into the settings file.
+ */
+class NodeJava
+{
+public:
+ enum Layer { USER_OR_INSTALL, USER, SHARED, INSTALL };
+private:
+
+ /** creates settings file and fills it with default values.
+
+ When this function is called then it creates the
+ settings file at the possition determined by the bootstrap parameters
+ (UNO_JAVA_JFW_USER_DATA, UNO_JAVA_JFW_SHARED_DATA,
+ UNO_JAVA_JFW_INSTALL_DATA) and m_layer, unless the file already exists
+ (see createSettingsDocument).
+
+ @return
+ JFW_E_CONFIG_READWRITE
+ */
+ void prepareSettingsDocument() const;
+
+ /** helper function for prepareSettingsDocument.
+ */
+ void createSettingsDocument() const;
+
+ /** returns the system path to the data file which is to be used. The value
+ depends on
+ the the member m_layer and the bootstrap paramters UNO_JAVA_JFW_USER_DATA,
+ UNO_JAVA_JFW_SHARED_DATA and UNO_JAVA_JFW_INSTALL_DATA which this may be.
+ */
+ ::rtl::OString getSettingsPath() const;
+
+ /** returns the file URL to the data file which is to be used. See getSettingsPath.
+ */
+ ::rtl::OUString getSettingsURL() const;
+
+ /** Verifies if the respective settings file exist. In case UNO_JAVA_JFW_INSTALL_DATA
+ is used, the age is checked. If the file is too old then we assume that it does not
+ exist and wipe its contents. Then still FILE_DOES_NOT_EXIST is returned.
+ */
+ jfw::FileStatus checkSettingsFileStatus() const;
+
+ /** Determines the layer for which the instance the loads and writes the
+ data.
+ */
+ Layer m_layer;
+
+ /** User configurable option. /java/enabled
+ If /java/enabled@xsi:nil == true then the value will be uninitialized
+ after a call to load().
+ */
+ boost::optional<sal_Bool> m_enabled;
+
+ /** User configurable option. /java/userClassPath
+ If /java/userClassPath@xsi:nil == true then the value is uninitialized
+ after a call to load().
+ */
+ boost::optional< ::rtl::OUString> m_userClassPath;
+ /** User configurable option. /java/javaInfo
+ If /java/javaInfo@xsi:nil == true then the value is uninitialized
+ after a call to load.
+ */
+ boost::optional<CNodeJavaInfo> m_javaInfo;
+ /** User configurable option. /java/vmParameters
+ If /java/vmParameters@xsi:nil == true then the value is uninitialized
+ after a call to load.
+ */
+ boost::optional< ::std::vector< ::rtl::OUString> > m_vmParameters;
+ /** User configurable option. /java/jreLocations
+ If /java/jreLocaltions@xsi:nil == true then the value is uninitialized
+ after a call to load.
+ */
+ boost::optional< ::std::vector< ::rtl::OUString> > m_JRELocations;
+
+ /** Only in INSTALL mode. Then NodeJava.write writes a <modified> element
+ which contains the seconds value of the TimeValue (osl/time.h), obtained
+ with osl_getSystemTime.
+ It returns 0 if the value cannot be obtained.
+ This is used to fix the problem that the modified time of the settings
+ file is incorrect because it resides on an NFS volume where the NFS
+ server and NFS client do not have the same system time. For example if
+ the server time is ahead of the client time then checkSettingsFileStatus
+ deleted the settings. So even if javaldx determined a Java
+ (jfw_findAndSelectJRE) then jfw_startVM returned a JFW_E_NO_SELECT. Then
+ it looked again for a java by calling jfw_findAndSelectJRE, which
+ returned a JFW_E_NONE. But the following jfw_startVM returned again
+ JFW_E_NO_SELECT. So it looped. (see issue i114509)
+
+ NFS server and NFS client should have the same time. It is common
+ practise to enforce this in networks. We actually should not work
+ around a malconfigured network. We must however, make sure that we do
+ not loop. Maybe a better approach is, that:
+ - assume that mtime and system time are reliable
+ - checkSettingsFile uses system time and mtime of the settings file,
+ instset of using getModifiedTime.
+ - allow a small error margin
+ - jfw_startVM must return a JFW_E_EXPIRED_SETTINGS
+ - XJavaVM::startVM should prevent the loop by processing the new return+ value
+
+ */
+ sal_uInt32 getModifiedTime() const;
+
+public:
+
+ NodeJava(Layer theLayer = USER_OR_INSTALL);
+
+ /** sets m_enabled.
+ /java/enabled@xsi:nil will be set to false when write is called.
+ */
+ void setEnabled(sal_Bool bEnabled);
+
+ /** sets m_sUserClassPath. See setEnabled.
+ */
+ void setUserClassPath(const ::rtl::OUString & sClassPath);
+
+ /** sets m_aInfo. See setEnabled.
+ @param bAutoSelect
+ true- called by jfw_setSelectedJRE
+ false called by jfw_findAndSelectJRE
+ */
+ void setJavaInfo(const JavaInfo * pInfo, bool bAutoSelect);
+
+ /** sets the /java/vmParameters/param elements.
+ When this method all previous values are removed and replaced
+ by those in arParameters.
+ /java/vmParameters@xsi:nil will be set to true when write() is
+ called.
+ */
+ void setVmParameters(rtl_uString * * arParameters, sal_Int32 size);
+
+ /** sets the /java/jreLocations/location elements.
+ When this method is called then all previous values are removed
+ and replaced by those in arParamters.
+ /java/jreLocations@xsi:nil will be set to true write() is called.
+ */
+ void setJRELocations(rtl_uString * * arParameters, sal_Int32 size);
+
+ /** adds a location to the already existing locations.
+ Note: call load() before, then add the location and then call write().
+ */
+ void addJRELocation(rtl_uString * sLocation);
+
+ /** writes the data to user settings.
+ */
+ void write() const;
+
+ /** load the values of the settings file.
+ */
+ void load();
+
+ /** returns the value of the element /java/enabled
+ */
+ const boost::optional<sal_Bool> & getEnabled() const;
+ /** returns the value of the element /java/userClassPath.
+ */
+ const boost::optional< ::rtl::OUString> & getUserClassPath() const;
+
+ /** returns the value of the element /java/javaInfo.
+ */
+ const boost::optional<CNodeJavaInfo> & getJavaInfo() const;
+
+ /** returns the parameters from the element /java/vmParameters/param.
+ */
+ const boost::optional< ::std::vector< ::rtl::OUString> > & getVmParameters() const;
+
+ /** returns the parameters from the element /java/jreLocations/location.
+ */
+ const boost::optional< ::std::vector< ::rtl::OUString> > & getJRELocations() const;
+};
+
+/** merges the settings for shared, user and installation during construction.
+ The class uses a simple merge mechanism for the javasettings.xml files in share and
+ user. The following elements completly overwrite the corresponding elements
+ from share:
+ /java/enabled
+ /java/userClassPath
+ /java/vmParameters
+ /java/jreLocations
+ /java/javaInfo
+
+ In case of an installation, the shared and user settings are completely
+ disregarded.
+
+ The locations of the different settings files is obtained through the
+ bootstrap variables:
+ UNO_JAVA_JFW_USER_DATA
+ UNO_JAVA_JFW_SHARED_DATA
+ UNO_JAVA_JFW_INSTALL_DATA
+
+ The class also determines useful default values for settings which have not been made.
+*/
+class MergedSettings
+{
+private:
+ const MergedSettings& operator = (MergedSettings&);
+ MergedSettings(MergedSettings&);
+
+ void merge(const NodeJava & share, const NodeJava & user);
+
+ sal_Bool m_bEnabled;
+
+ ::rtl::OUString m_sClassPath;
+
+ ::std::vector< ::rtl::OUString> m_vmParams;
+
+ ::std::vector< ::rtl::OUString> m_JRELocations;
+
+ CNodeJavaInfo m_javaInfo;
+
+public:
+ MergedSettings();
+ virtual ~MergedSettings();
+
+ /** the default is true.
+ */
+ sal_Bool getEnabled() const;
+
+ const ::rtl::OUString & getUserClassPath() const;
+
+ ::std::vector< ::rtl::OString> getVmParametersUtf8() const;
+ /** returns a JavaInfo structure representing the node
+ /java/javaInfo. Every time a new JavaInfo structure is created
+ which needs to be freed by the caller.
+ If both, user and share settings are nil, then NULL is returned.
+ */
+ JavaInfo * createJavaInfo() const;
+
+ /** returns the value of the attribute /java/javaInfo[@vendorUpdate].
+ */
+ ::rtl::OString const & getJavaInfoAttrVendorUpdate() const;
+
+#ifdef WNT
+ /** returns the javaInfo@autoSelect attribute.
+ Before calling this function loadFromSettings must be called.
+ It uses the javaInfo@autoSelect attribute to determine
+ the return value;
+ */
+ bool getJavaInfoAttrAutoSelect() const;
+#endif
+
+ /** returns an array.
+ Caller must free the strings and the array.
+ */
+ void getVmParametersArray(rtl_uString *** parParameters, sal_Int32 * size) const;
+
+ /** returns an array.
+ Caller must free the strings and the array.
+ */
+ void getJRELocations(rtl_uString *** parLocations, sal_Int32 * size) const;
+
+ const ::std::vector< ::rtl::OUString> & getJRELocations() const;
+};
+
+
+class VersionInfo
+{
+ ::std::vector< ::rtl::OUString> vecExcludeVersions;
+ rtl_uString ** arVersions;
+
+public:
+ VersionInfo();
+ ~VersionInfo();
+
+ void addExcludeVersion(const ::rtl::OUString& sVersion);
+
+ ::rtl::OUString sMinVersion;
+ ::rtl::OUString sMaxVersion;
+
+ /** The caller DOES NOT get ownership of the strings. That is he
+ does not need to release the strings.
+ The array exists as long as this object exists.
+ */
+
+ rtl_uString** getExcludeVersions();
+ sal_Int32 getExcludeVersionSize();
+};
+
+struct PluginLibrary
+{
+ PluginLibrary()
+ {
+ }
+ PluginLibrary(rtl::OUString vendor,::rtl::OUString path) :
+ sVendor(vendor), sPath(path)
+ {
+ }
+ /** contains the vendor string which is later userd in the xml API
+ */
+ ::rtl::OUString sVendor;
+ /** File URL the plug-in library
+ */
+ ::rtl::OUString sPath;
+};
+
+} //end namespace
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/jvmfwk/source/framework.cxx b/jvmfwk/source/framework.cxx
new file mode 100644
index 000000000000..cd74131b24b2
--- /dev/null
+++ b/jvmfwk/source/framework.cxx
@@ -0,0 +1,1284 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_jvmfwk.hxx"
+#include "boost/scoped_array.hpp"
+#include "rtl/ustring.hxx"
+#include "rtl/bootstrap.hxx"
+#include "osl/thread.hxx"
+#include "osl/file.hxx"
+#include "osl/module.hxx"
+#include "jvmfwk/framework.h"
+#include "jvmfwk/vendorplugin.h"
+#include <vector>
+#include <functional>
+#include <algorithm>
+#include "framework.hxx"
+#include "fwkutil.hxx"
+#include "elements.hxx"
+#include "fwkbase.hxx"
+
+#ifdef WNT
+/** The existence of the file useatjava.txt decides if a Java should be used
+ that supports accessibility tools.
+ */
+#define USE_ACCESSIBILITY_FILE "useatjava.txt"
+#endif
+
+#define UNO_JAVA_JFW_JREHOME "UNO_JAVA_JFW_JREHOME"
+namespace {
+JavaVM * g_pJavaVM = NULL;
+
+bool g_bEnabledSwitchedOn = false;
+
+sal_Bool areEqualJavaInfo(
+ JavaInfo const * pInfoA,JavaInfo const * pInfoB)
+{
+ return jfw_areEqualJavaInfo(pInfoA, pInfoB);
+}
+}
+
+javaFrameworkError SAL_CALL jfw_findAllJREs(JavaInfo ***pparInfo, sal_Int32 *pSize)
+{
+ javaFrameworkError retVal = JFW_E_NONE;
+ try
+ {
+ osl::MutexGuard guard(jfw::FwkMutex::get());
+ javaFrameworkError errcode = JFW_E_NONE;
+ if (pparInfo == NULL || pSize == NULL)
+ return JFW_E_INVALID_ARG;
+
+ jfw::VendorSettings aVendorSettings;
+ //Get a list of plugins which provide Java information
+ std::vector<jfw::PluginLibrary> vecPlugins =
+ aVendorSettings.getPluginData();
+
+ //Create a vector that holds the libraries, which will be later
+ //dynamically loaded;
+ boost::scoped_array<osl::Module> sarModules;
+ sarModules.reset(new osl::Module[vecPlugins.size()]);
+ osl::Module * arModules = sarModules.get();
+ //Add the JavaInfos found by jfw_plugin_getAllJavaInfos to the vector
+ //Make sure that the contents are destroyed if this
+ //function returns with an error
+ std::vector<jfw::CJavaInfo> vecInfo;
+ //Add the JavaInfos found by jfw_plugin_getJavaInfoByPath to this vector
+ //Make sure that the contents are destroyed if this
+ //function returns with an error
+ std::vector<jfw::CJavaInfo> vecInfoManual;
+ typedef std::vector<jfw::CJavaInfo>::iterator it_info;
+ //get the list of paths to jre locations which have been
+ //added manually
+ const jfw::MergedSettings settings;
+ const std::vector<rtl::OUString>& vecJRELocations =
+ settings.getJRELocations();
+ //Use every plug-in library to get Java installations.
+ typedef std::vector<jfw::PluginLibrary>::const_iterator ci_pl;
+ int cModule = 0;
+ for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); ++i, ++cModule)
+ {
+ const jfw::PluginLibrary & library = *i;
+ jfw::VersionInfo versionInfo =
+ aVendorSettings.getVersionInformation(library.sVendor);
+ arModules[cModule].load(library.sPath);
+ osl::Module & pluginLib = arModules[cModule];
+
+ if (pluginLib.is() == sal_False)
+ {
+ rtl::OString msg = rtl::OUStringToOString(
+ library.sPath, osl_getThreadTextEncoding());
+ fprintf(stderr,"[jvmfwk] Could not load plugin %s\n" \
+ "Modify the javavendors.xml accordingly!\n", msg.getStr());
+ return JFW_E_NO_PLUGIN;
+ }
+ jfw_plugin_getAllJavaInfos_ptr getAllJavaFunc =
+ (jfw_plugin_getAllJavaInfos_ptr) pluginLib.getFunctionSymbol(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getAllJavaInfos")));
+
+ OSL_ASSERT(getAllJavaFunc);
+ if (getAllJavaFunc == NULL)
+ return JFW_E_ERROR;
+
+ //get all installations of one vendor according to minVersion,
+ //maxVersion and excludeVersions
+ sal_Int32 cInfos = 0;
+ JavaInfo** arInfos = NULL;
+ javaPluginError plerr = (*getAllJavaFunc)(
+ library.sVendor.pData,
+ versionInfo.sMinVersion.pData,
+ versionInfo.sMaxVersion.pData,
+ versionInfo.getExcludeVersions(),
+ versionInfo.getExcludeVersionSize(),
+ & arInfos,
+ & cInfos);
+
+ if (plerr != JFW_PLUGIN_E_NONE)
+ return JFW_E_ERROR;
+
+ for (int j = 0; j < cInfos; j++)
+ vecInfo.push_back(jfw::CJavaInfo::createWrapper(arInfos[j]));
+
+ rtl_freeMemory(arInfos);
+
+ //Check if the current plugin can detect JREs at the location
+ // of the paths added by jfw_setJRELocations or jfw_addJRELocation
+ //get the function from the plugin
+ jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc =
+ (jfw_plugin_getJavaInfoByPath_ptr) pluginLib.getFunctionSymbol(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getJavaInfoByPath")));
+
+ OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc);
+ if (jfw_plugin_getJavaInfoByPathFunc == NULL)
+ return JFW_E_ERROR;
+
+ typedef std::vector<rtl::OUString>::const_iterator citLoc;
+ //Check every manually added location
+ for (citLoc ii = vecJRELocations.begin();
+ ii != vecJRELocations.end(); ++ii)
+ {
+ jfw::CJavaInfo aInfo;
+ plerr = (*jfw_plugin_getJavaInfoByPathFunc)(
+ ii->pData,
+ library.sVendor.pData,
+ versionInfo.sMinVersion.pData,
+ versionInfo.sMaxVersion.pData,
+ versionInfo.getExcludeVersions(),
+ versionInfo.getExcludeVersionSize(),
+ & aInfo.pInfo);
+ if (plerr == JFW_PLUGIN_E_NO_JRE)
+ continue;
+ if (plerr == JFW_PLUGIN_E_FAILED_VERSION)
+ continue;
+ else if (plerr !=JFW_PLUGIN_E_NONE)
+ return JFW_E_ERROR;
+
+ if (aInfo)
+ {
+ //Was this JRE already added?. Different plugins could detect
+ //the same JRE
+ it_info it_duplicate =
+ std::find_if(vecInfoManual.begin(), vecInfoManual.end(),
+ std::bind2nd(std::ptr_fun(areEqualJavaInfo), aInfo));
+ if (it_duplicate == vecInfoManual.end())
+ vecInfoManual.push_back(aInfo);
+ }
+ }
+ }
+ //Make sure vecInfoManual contains only JavaInfos for the vendors for which
+ //there is a javaSelection/plugins/library entry in the javavendors.xml
+ //To obtain the JavaInfos for the manually added JRE locations the function
+ //jfw_getJavaInfoByPath is called which can return a JavaInfo of any vendor.
+ std::vector<jfw::CJavaInfo> vecInfoManual2;
+ for (it_info ivm = vecInfoManual.begin(); ivm != vecInfoManual.end(); ++ivm)
+ {
+ for (ci_pl ii = vecPlugins.begin(); ii != vecPlugins.end(); ++ii)
+ {
+ if ( ii->sVendor.equals((*ivm)->sVendor))
+ {
+ vecInfoManual2.push_back(*ivm);
+ break;
+ }
+ }
+ }
+ //Check which JavaInfo from vector vecInfoManual2 is already
+ //contained in vecInfo. If it already exists then remove it from
+ //vecInfoManual2
+ for (it_info j = vecInfo.begin(); j != vecInfo.end(); ++j)
+ {
+ it_info it_duplicate =
+ std::find_if(vecInfoManual2.begin(), vecInfoManual2.end(),
+ std::bind2nd(std::ptr_fun(areEqualJavaInfo), *j));
+ if (it_duplicate != vecInfoManual2.end())
+ vecInfoManual2.erase(it_duplicate);
+ }
+ //create an fill the array of JavaInfo*
+ sal_Int32 nSize = vecInfo.size() + vecInfoManual2.size();
+ *pparInfo = (JavaInfo**) rtl_allocateMemory(
+ nSize * sizeof(JavaInfo*));
+ if (*pparInfo == NULL)
+ return JFW_E_ERROR;
+
+ typedef std::vector<jfw::CJavaInfo>::iterator it;
+ int index = 0;
+ //Add the automatically detected JREs
+ for (it k = vecInfo.begin(); k != vecInfo.end(); ++k)
+ (*pparInfo)[index++] = k->detach();
+ //Add the manually detected JREs
+ for (it l = vecInfoManual2.begin(); l != vecInfoManual2.end(); ++l)
+ (*pparInfo)[index++] = l->detach();
+
+ *pSize = nSize;
+ return errcode;
+ }
+ catch (jfw::FrameworkException& e)
+ {
+ retVal = e.errorCode;
+ fprintf(stderr, "%s\n", e.message.getStr());
+ OSL_FAIL(e.message.getStr());
+ }
+ return retVal;
+}
+
+javaFrameworkError SAL_CALL jfw_startVM(JavaVMOption *arOptions, sal_Int32 cOptions,
+ JavaVM **ppVM, JNIEnv **ppEnv)
+{
+#ifndef SOLAR_JAVA
+ return JFW_E_ERROR;
+#else
+ javaFrameworkError errcode = JFW_E_NONE;
+ if (cOptions > 0 && arOptions == NULL)
+ return JFW_E_INVALID_ARG;
+
+ try
+ {
+ osl::MutexGuard guard(jfw::FwkMutex::get());
+
+ //We keep this pointer so we can determine if a VM has already
+ //been created.
+ if (g_pJavaVM != NULL)
+ return JFW_E_RUNNING_JVM;
+
+ if (ppVM == NULL)
+ return JFW_E_INVALID_ARG;
+
+ std::vector<rtl::OString> vmParams;
+ rtl::OString sUserClassPath;
+ jfw::CJavaInfo aInfo;
+ jfw::JFW_MODE mode = jfw::getMode();
+ if (mode == jfw::JFW_MODE_APPLICATION)
+ {
+ const jfw::MergedSettings settings;
+ if (sal_False == settings.getEnabled())
+ return JFW_E_JAVA_DISABLED;
+ aInfo.attach(settings.createJavaInfo());
+ //check if a Java has ever been selected
+ if (aInfo == NULL)
+ return JFW_E_NO_SELECT;
+
+#ifdef WNT
+ //Because on Windows there is no system setting that we can use to determine
+ //if Assistive Technology Tool support is needed, we ship a .reg file that the
+ //user can use to create a registry setting. When the user forgets to set
+ //the key before he starts the office then a JRE may be selected without access bridge.
+ //When he later sets the key then we select a JRE with accessibility support but
+ //only if the user has not manually changed the selected JRE in the options dialog.
+ if (jfw::isAccessibilitySupportDesired())
+ {
+ // If no JRE has been selected then we do not select one. This function shall then
+ //return JFW_E_NO_SELECT
+ if (aInfo != NULL &&
+ (aInfo->nFeatures & JFW_FEATURE_ACCESSBRIDGE) == 0)
+ {
+ //has the user manually selected a JRE?
+ if (settings.getJavaInfoAttrAutoSelect() == true)
+ {
+ // if not then the automatism has previously selected a JRE
+ //without accessibility support. We return JFW_E_NO_SELECT
+ //to cause that we search for another JRE. The search code will
+ //then prefer a JRE with accessibility support.
+ return JFW_E_NO_SELECT;
+ }
+ }
+ }
+#endif
+ //check if the javavendors.xml has changed after a Java was selected
+ rtl::OString sVendorUpdate = jfw::getElementUpdated();
+
+ if (sVendorUpdate != settings.getJavaInfoAttrVendorUpdate())
+ return JFW_E_INVALID_SETTINGS;
+
+ //check if JAVA is disabled
+ //If Java is enabled, but it was disabled when this process was started
+ // then no preparational work, such as setting the LD_LIBRARY_PATH, was
+ //done. Therefore if a JRE needs it it must not be started.
+ if (g_bEnabledSwitchedOn &&
+ (aInfo->nRequirements & JFW_REQUIRE_NEEDRESTART))
+ return JFW_E_NEED_RESTART;
+
+ //Check if the selected Java was set in this process. If so it
+ //must not have the requirments flag JFW_REQUIRE_NEEDRESTART
+ if ((aInfo->nRequirements & JFW_REQUIRE_NEEDRESTART)
+ &&
+ (jfw::wasJavaSelectedInSameProcess() == true))
+ return JFW_E_NEED_RESTART;
+
+ vmParams = settings.getVmParametersUtf8();
+ sUserClassPath = jfw::makeClassPathOption(settings.getUserClassPath());
+ } // end mode FWK_MODE_OFFICE
+ else if (mode == jfw::JFW_MODE_DIRECT)
+ {
+ errcode = jfw_getSelectedJRE(&aInfo.pInfo);
+ if (errcode != JFW_E_NONE)
+ return errcode;
+ //In direct mode the options are specified by bootstrap variables
+ //of the form UNO_JAVA_JFW_PARAMETER_1 .. UNO_JAVA_JFW_PARAMETER_n
+ vmParams = jfw::BootParams::getVMParameters();
+ sUserClassPath =
+ "-Djava.class.path=" + jfw::BootParams::getClasspath();
+ }
+ else
+ OSL_ASSERT(0);
+
+ //get the function jfw_plugin_startJavaVirtualMachine
+ jfw::VendorSettings aVendorSettings;
+ rtl::OUString sLibPath = aVendorSettings.getPluginLibrary(aInfo.getVendor());
+
+ osl::Module modulePlugin(sLibPath);
+ if ( ! modulePlugin)
+ return JFW_E_NO_PLUGIN;
+
+ rtl::OUString sFunctionName(
+ RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_startJavaVirtualMachine"));
+ jfw_plugin_startJavaVirtualMachine_ptr pFunc =
+ (jfw_plugin_startJavaVirtualMachine_ptr)
+ osl_getFunctionSymbol(modulePlugin, sFunctionName.pData);
+ if (pFunc == NULL)
+ return JFW_E_ERROR;
+
+ // create JavaVMOptions array that is passed to the plugin
+ // it contains the classpath and all options set in the
+ //options dialog
+ boost::scoped_array<JavaVMOption> sarJOptions(
+ new JavaVMOption[cOptions + 2 + vmParams.size()]);
+ JavaVMOption * arOpt = sarJOptions.get();
+ if (! arOpt)
+ return JFW_E_ERROR;
+
+ //The first argument is the classpath
+ arOpt[0].optionString= (char*) sUserClassPath.getStr();
+ arOpt[0].extraInfo = NULL;
+ // Set a flag that this JVM has been created via the JNI Invocation API
+ // (used, for example, by UNO remote bridges to share a common thread pool
+ // factory among Java and native bridge implementations):
+ arOpt[1].optionString = (char *) "-Dorg.openoffice.native=";
+ arOpt[1].extraInfo = 0;
+
+ //add the options set by options dialog
+ int index = 2;
+ typedef std::vector<rtl::OString>::const_iterator cit;
+ for (cit i = vmParams.begin(); i != vmParams.end(); ++i)
+ {
+ arOpt[index].optionString = const_cast<sal_Char*>(i->getStr());
+ arOpt[index].extraInfo = 0;
+ index ++;
+ }
+ //add all options of the arOptions argument
+ for (int ii = 0; ii < cOptions; ii++)
+ {
+ arOpt[index].optionString = arOptions[ii].optionString;
+ arOpt[index].extraInfo = arOptions[ii].extraInfo;
+ index++;
+ }
+
+ //start Java
+ JavaVM *pVm = NULL;
+ javaPluginError plerr = (*pFunc)(aInfo, arOpt, index, & pVm, ppEnv);
+ if (plerr == JFW_PLUGIN_E_VM_CREATION_FAILED)
+ {
+ errcode = JFW_E_VM_CREATION_FAILED;
+ }
+ else if (plerr != JFW_PLUGIN_E_NONE )
+ {
+ errcode = JFW_E_ERROR;
+ }
+ else
+ {
+ g_pJavaVM = pVm;
+ *ppVM = pVm;
+ }
+ OSL_ASSERT(plerr != JFW_PLUGIN_E_WRONG_VENDOR);
+ }
+ catch (jfw::FrameworkException& e)
+ {
+ errcode = e.errorCode;
+ fprintf(stderr, "%s\n", e.message.getStr());
+ OSL_FAIL(e.message.getStr());
+ }
+
+ return errcode;
+#endif
+}
+
+/** We do not use here jfw_findAllJREs and then check if a JavaInfo
+ meets the requirements, because that means using all plug-ins, which
+ may take quite a while. The implementation uses one plug-in and if
+ it already finds a suitable JRE then it is done and does not need to
+ load another plug-in
+ */
+javaFrameworkError SAL_CALL jfw_findAndSelectJRE(JavaInfo **pInfo)
+{
+ javaFrameworkError errcode = JFW_E_NONE;
+ try
+ {
+ osl::MutexGuard guard(jfw::FwkMutex::get());
+ if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
+ return JFW_E_DIRECT_MODE;
+ sal_uInt64 nFeatureFlags = 0;
+ jfw::CJavaInfo aCurrentInfo;
+//Determine if accessibility support is needed
+ bool bSupportAccessibility = jfw::isAccessibilitySupportDesired();
+ nFeatureFlags = bSupportAccessibility ?
+ JFW_FEATURE_ACCESSBRIDGE : 0L;
+
+ //Get a list of services which provide Java information
+ jfw::VendorSettings aVendorSettings;
+ std::vector<jfw::PluginLibrary> vecPlugins =
+ aVendorSettings.getPluginData();
+ //Create a vector that holds the libraries, which will be later
+ //dynamically loaded;
+ boost::scoped_array<osl::Module> sarModules;
+ sarModules.reset(new osl::Module[vecPlugins.size()]);
+ osl::Module * arModules = sarModules.get();
+
+ //Use every plug-in library to get Java installations. At the first usable
+ //Java the loop will break
+ typedef std::vector<jfw::PluginLibrary>::const_iterator ci_pl;
+ int cModule = 0;
+ for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); ++i, ++cModule)
+ {
+ const jfw::PluginLibrary & library = *i;
+ jfw::VersionInfo versionInfo =
+ aVendorSettings.getVersionInformation(library.sVendor);
+
+ arModules[cModule].load(library.sPath);
+ osl::Module & pluginLib = arModules[cModule];
+ if (pluginLib.is() == sal_False)
+ return JFW_E_NO_PLUGIN;
+
+ jfw_plugin_getAllJavaInfos_ptr getAllJavaFunc =
+ (jfw_plugin_getAllJavaInfos_ptr) pluginLib.getFunctionSymbol(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getAllJavaInfos")));
+
+ OSL_ASSERT(getAllJavaFunc);
+ if (getAllJavaFunc == NULL)
+ continue;
+
+ //get all installations of one vendor according to minVersion,
+ //maxVersion and excludeVersions
+ sal_Int32 cInfos = 0;
+ JavaInfo** arInfos = NULL;
+ javaPluginError plerr = (*getAllJavaFunc)(
+ library.sVendor.pData,
+ versionInfo.sMinVersion.pData,
+ versionInfo.sMaxVersion.pData,
+ versionInfo.getExcludeVersions(),
+ versionInfo.getExcludeVersionSize(),
+ & arInfos,
+ & cInfos);
+
+ if (plerr != JFW_PLUGIN_E_NONE)
+ continue;
+ //iterate over all installations to find the best which has
+ //all features
+ if (cInfos == 0)
+ {
+ rtl_freeMemory(arInfos);
+ continue;
+ }
+ bool bInfoFound = false;
+ for (int ii = 0; ii < cInfos; ii++)
+ {
+ JavaInfo* pJInfo = arInfos[ii];
+
+ //We remember the very first installation in aCurrentInfo
+ if (aCurrentInfo.getLocation().getLength() == 0)
+ aCurrentInfo = pJInfo;
+ // compare features
+ // If the user does not require any features (nFeatureFlags = 0)
+ // then the first installation is used
+ if ((pJInfo->nFeatures & nFeatureFlags) == nFeatureFlags)
+ {
+ //the just found Java implements all required features
+ //currently there is only accessibility!!!
+ aCurrentInfo = pJInfo;
+ bInfoFound = true;
+ break;
+ }
+ }
+ //The array returned by jfw_plugin_getAllJavaInfos must be freed as well as
+ //its contents
+ for (int j = 0; j < cInfos; j++)
+ jfw_freeJavaInfo(arInfos[j]);
+ rtl_freeMemory(arInfos);
+
+ if (bInfoFound == true)
+ break;
+ //All Java installations found by the current plug-in lib
+ //do not provide the required features. Try the next plug-in
+ }
+ if ((JavaInfo*) aCurrentInfo == NULL)
+ {//The plug-ins did not find a suitable Java. Now try the paths which have been
+ //added manually.
+ //get the list of paths to jre locations which have been added manually
+ const jfw::MergedSettings settings;
+ //node.loadFromSettings();
+ const std::vector<rtl::OUString> & vecJRELocations =
+ settings.getJRELocations();
+ //use every plug-in to determine the JavaInfo objects
+ bool bInfoFound = false;
+ for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end(); ++i)
+ {
+ const jfw::PluginLibrary & library = *i;
+ jfw::VersionInfo versionInfo =
+ aVendorSettings.getVersionInformation(library.sVendor);
+
+ osl::Module pluginLib(library.sPath);
+ if (pluginLib.is() == sal_False)
+ return JFW_E_NO_PLUGIN;
+ //Check if the current plugin can detect JREs at the location
+ // of the paths added by jfw_setJRELocations or jfw_addJRELocation
+ //get the function from the plugin
+ jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc =
+ (jfw_plugin_getJavaInfoByPath_ptr) pluginLib.getFunctionSymbol(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getJavaInfoByPath")));
+
+ OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc);
+ if (jfw_plugin_getJavaInfoByPathFunc == NULL)
+ return JFW_E_ERROR;
+
+ typedef std::vector<rtl::OUString>::const_iterator citLoc;
+ for (citLoc it = vecJRELocations.begin();
+ it != vecJRELocations.end(); ++it)
+ {
+ jfw::CJavaInfo aInfo;
+ javaPluginError err = (*jfw_plugin_getJavaInfoByPathFunc)(
+ it->pData,
+ library.sVendor.pData,
+ versionInfo.sMinVersion.pData,
+ versionInfo.sMaxVersion.pData,
+ versionInfo.getExcludeVersions(),
+ versionInfo.getExcludeVersionSize(),
+ & aInfo.pInfo);
+ if (err == JFW_PLUGIN_E_NO_JRE)
+ continue;
+ if (err == JFW_PLUGIN_E_FAILED_VERSION)
+ continue;
+ else if (err !=JFW_PLUGIN_E_NONE)
+ return JFW_E_ERROR;
+
+ if (aInfo)
+ {
+ //We remember the very first installation in aCurrentInfo
+ if (aCurrentInfo.getLocation().getLength() == 0)
+ aCurrentInfo = aInfo;
+ // compare features
+ // If the user does not require any features (nFeatureFlags = 0)
+ // then the first installation is used
+ if ((aInfo.getFeatures() & nFeatureFlags) == nFeatureFlags)
+ {
+ //the just found Java implements all required features
+ //currently there is only accessibility!!!
+ aCurrentInfo = aInfo;
+ bInfoFound = true;
+ break;
+ }
+ }
+ }//end iterate over paths
+ if (bInfoFound == true)
+ break;
+ }// end iterate plug-ins
+ }
+ if ((JavaInfo*) aCurrentInfo)
+ {
+ jfw::NodeJava javaNode;
+ javaNode.setJavaInfo(aCurrentInfo,true);
+ javaNode.write();
+
+ if (pInfo !=NULL)
+ {
+ //copy to out param
+ *pInfo = aCurrentInfo.cloneJavaInfo();
+ //remember that this JRE was selected in this process
+ jfw::setJavaSelected();
+ }
+ }
+ else
+ {
+ errcode = JFW_E_NO_JAVA_FOUND;
+ }
+ }
+ catch (jfw::FrameworkException& e)
+ {
+ errcode = e.errorCode;
+ fprintf(stderr, "%s\n", e.message.getStr());
+ OSL_FAIL(e.message.getStr());
+ }
+
+ return errcode;
+}
+sal_Bool SAL_CALL jfw_areEqualJavaInfo(
+ JavaInfo const * pInfoA,JavaInfo const * pInfoB)
+{
+ if (pInfoA == pInfoB)
+ return sal_True;
+ if (pInfoA == NULL || pInfoB == NULL)
+ return sal_False;
+ rtl::OUString sVendor(pInfoA->sVendor);
+ rtl::OUString sLocation(pInfoA->sLocation);
+ rtl::OUString sVersion(pInfoA->sVersion);
+ rtl::ByteSequence sData(pInfoA->arVendorData);
+ if (sVendor.equals(pInfoB->sVendor) == sal_True
+ && sLocation.equals(pInfoB->sLocation) == sal_True
+ && sVersion.equals(pInfoB->sVersion) == sal_True
+ && pInfoA->nFeatures == pInfoB->nFeatures
+ && pInfoA->nRequirements == pInfoB->nRequirements
+ && sData == pInfoB->arVendorData)
+ {
+ return sal_True;
+ }
+ return sal_False;
+}
+
+
+void SAL_CALL jfw_freeJavaInfo(JavaInfo *pInfo)
+{
+ if (pInfo == NULL)
+ return;
+ rtl_uString_release(pInfo->sVendor);
+ rtl_uString_release(pInfo->sLocation);
+ rtl_uString_release(pInfo->sVersion);
+ rtl_byte_sequence_release(pInfo->arVendorData);
+ rtl_freeMemory(pInfo);
+}
+
+javaFrameworkError SAL_CALL jfw_getSelectedJRE(JavaInfo **ppInfo)
+{
+ javaFrameworkError errcode = JFW_E_NONE;
+ try
+ {
+ osl::MutexGuard guard(jfw::FwkMutex::get());
+ if (ppInfo == NULL)
+ return JFW_E_INVALID_ARG;
+
+ if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
+ {
+ rtl::OUString sJRE = jfw::BootParams::getJREHome();
+
+ jfw::CJavaInfo aInfo;
+ if ((errcode = jfw_getJavaInfoByPath(sJRE.pData, & aInfo.pInfo))
+ != JFW_E_NONE)
+ throw jfw::FrameworkException(
+ JFW_E_CONFIGURATION,
+ rtl::OString(
+ "[Java framework] The JRE specified by the bootstrap "
+ "variable UNO_JAVA_JFW_JREHOME or UNO_JAVA_JFW_ENV_JREHOME "
+ " could not be recognized. Check the values and make sure that you "
+ "use a plug-in library that can recognize that JRE."));
+
+ *ppInfo = aInfo.detach();
+ return JFW_E_NONE;
+ }
+
+ const jfw::MergedSettings settings;
+ jfw::CJavaInfo aInfo;
+ aInfo.attach(settings.createJavaInfo());
+ if (! aInfo)
+ {
+ *ppInfo = NULL;
+ return JFW_E_NONE;
+ }
+ //If the javavendors.xml has changed, then the current selected
+ //Java is not valid anymore
+ // /java/javaInfo/@vendorUpdate != javaSelection/updated (javavendors.xml)
+ rtl::OString sUpdated = jfw::getElementUpdated();
+
+ if (sUpdated.equals(settings.getJavaInfoAttrVendorUpdate()) == sal_False)
+ return JFW_E_INVALID_SETTINGS;
+ *ppInfo = aInfo.detach();
+ }
+ catch (jfw::FrameworkException& e)
+ {
+ errcode = e.errorCode;
+ fprintf(stderr, "%s\n", e.message.getStr());
+ OSL_FAIL(e.message.getStr());
+ }
+ return errcode;
+}
+
+javaFrameworkError SAL_CALL jfw_isVMRunning(sal_Bool *bRunning)
+{
+ osl::MutexGuard guard(jfw::FwkMutex::get());
+ if (bRunning == NULL)
+ return JFW_E_INVALID_ARG;
+ if (g_pJavaVM == NULL)
+ *bRunning = sal_False;
+ else
+ *bRunning = sal_True;
+ return JFW_E_NONE;
+}
+
+javaFrameworkError SAL_CALL jfw_getJavaInfoByPath(
+ rtl_uString *pPath, JavaInfo **ppInfo)
+{
+ javaFrameworkError errcode = JFW_E_NONE;
+ try
+ {
+ osl::MutexGuard guard(jfw::FwkMutex::get());
+ if (pPath == NULL || ppInfo == NULL)
+ return JFW_E_INVALID_ARG;
+
+ jfw::VendorSettings aVendorSettings;
+ //Get a list of plugins which provide Java information
+ std::vector<jfw::PluginLibrary> vecPlugins =
+ aVendorSettings.getPluginData();
+ //Create a vector that holds the libraries, which will be later
+ //dynamically loaded;
+ boost::scoped_array<osl::Module> sarModules;
+ sarModules.reset(new osl::Module[vecPlugins.size()]);
+ osl::Module * arModules = sarModules.get();
+
+ typedef std::vector<rtl::OUString>::const_iterator CIT_VENDOR;
+ std::vector<rtl::OUString> vecVendors =
+ aVendorSettings.getSupportedVendors();
+
+ //Use every plug-in library to determine if the path represents a
+ //JRE. If a plugin recognized it then the loop will break
+ typedef std::vector<jfw::PluginLibrary>::const_iterator ci_pl;
+ int cModule = 0;
+ for (ci_pl i = vecPlugins.begin(); i != vecPlugins.end();
+ ++i, ++cModule)
+ {
+ const jfw::PluginLibrary & library = *i;
+ jfw::VersionInfo versionInfo =
+ aVendorSettings.getVersionInformation(library.sVendor);
+ arModules[cModule].load(library.sPath);
+ osl::Module & pluginLib = arModules[cModule];
+ if (pluginLib.is() == sal_False)
+ {
+ rtl::OString msg = rtl::OUStringToOString(
+ library.sPath, osl_getThreadTextEncoding());
+ fprintf(stderr,"[jvmfwk] Could not load plugin %s\n" \
+ "Modify the javavendors.xml accordingly!\n", msg.getStr());
+ return JFW_E_NO_PLUGIN;
+ }
+
+ jfw_plugin_getJavaInfoByPath_ptr jfw_plugin_getJavaInfoByPathFunc =
+ (jfw_plugin_getJavaInfoByPath_ptr) pluginLib.getFunctionSymbol(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_getJavaInfoByPath")));
+
+ OSL_ASSERT(jfw_plugin_getJavaInfoByPathFunc);
+ if (jfw_plugin_getJavaInfoByPathFunc == NULL)
+ continue;
+
+ //ask the plugin if this is a JRE.
+ //If so check if it meets the version requirements.
+ //Only if it does return a JavaInfo
+ JavaInfo* pInfo = NULL;
+ javaPluginError plerr = (*jfw_plugin_getJavaInfoByPathFunc)(
+ pPath,
+ library.sVendor.pData,
+ versionInfo.sMinVersion.pData,
+ versionInfo.sMaxVersion.pData,
+ versionInfo.getExcludeVersions(),
+ versionInfo.getExcludeVersionSize(),
+ & pInfo);
+
+ if (plerr == JFW_PLUGIN_E_NONE)
+ {
+ //check if the vendor of the found JRE is supported
+ if (vecVendors.size() == 0)
+ {
+ //vendor does not matter
+ *ppInfo = pInfo;
+ break;
+ }
+ else
+ {
+ rtl::OUString sVendor(pInfo->sVendor);
+ CIT_VENDOR ivendor = std::find(vecVendors.begin(), vecVendors.end(),
+ sVendor);
+ if (ivendor != vecVendors.end())
+ {
+ *ppInfo = pInfo;
+ }
+ else
+ {
+ *ppInfo = NULL;
+ errcode = JFW_E_NOT_RECOGNIZED;
+ }
+ break;
+ }
+ }
+ else if(plerr == JFW_PLUGIN_E_FAILED_VERSION)
+ {//found JRE but it has the wrong version
+ *ppInfo = NULL;
+ errcode = JFW_E_FAILED_VERSION;
+ break;
+ }
+ else if (plerr == JFW_PLUGIN_E_NO_JRE)
+ {// plugin does not recognize this path as belonging to JRE
+ continue;
+ }
+ OSL_ASSERT(0);
+ }
+ if (*ppInfo == NULL && errcode != JFW_E_FAILED_VERSION)
+ errcode = JFW_E_NOT_RECOGNIZED;
+ }
+ catch (jfw::FrameworkException& e)
+ {
+ errcode = e.errorCode;
+ fprintf(stderr, "%s\n", e.message.getStr());
+ OSL_FAIL(e.message.getStr());
+ }
+
+ return errcode;
+}
+
+
+javaFrameworkError SAL_CALL jfw_setSelectedJRE(JavaInfo const *pInfo)
+{
+ javaFrameworkError errcode = JFW_E_NONE;
+ try
+ {
+ osl::MutexGuard guard(jfw::FwkMutex::get());
+ if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
+ return JFW_E_DIRECT_MODE;
+ //check if pInfo is the selected JRE
+ JavaInfo *currentInfo = NULL;
+ errcode = jfw_getSelectedJRE( & currentInfo);
+ if (errcode != JFW_E_NONE && errcode != JFW_E_INVALID_SETTINGS)
+ return errcode;
+
+ if (jfw_areEqualJavaInfo(currentInfo, pInfo) == sal_False)
+ {
+ jfw::NodeJava node;
+ node.setJavaInfo(pInfo, false);
+ node.write();
+ //remember that the JRE was selected in this process
+ jfw::setJavaSelected();
+ }
+ }
+ catch (jfw::FrameworkException& e)
+ {
+ errcode = e.errorCode;
+ fprintf(stderr, "%s\n", e.message.getStr());
+ OSL_FAIL(e.message.getStr());
+ }
+ return errcode;
+}
+javaFrameworkError SAL_CALL jfw_setEnabled(sal_Bool bEnabled)
+{
+ javaFrameworkError errcode = JFW_E_NONE;
+ try
+ {
+ osl::MutexGuard guard(jfw::FwkMutex::get());
+ if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
+ return JFW_E_DIRECT_MODE;
+
+ if (g_bEnabledSwitchedOn == false && bEnabled == sal_True)
+ {
+ //When the process started then Enabled was false.
+ //This is first time enabled is set to true.
+ //That means, no preparational work has been done, such as setting the
+ //LD_LIBRARY_PATH, etc.
+
+ //check if Enabled is false;
+ const jfw::MergedSettings settings;
+ if (settings.getEnabled() == sal_False)
+ g_bEnabledSwitchedOn = true;
+ }
+ jfw::NodeJava node;
+ node.setEnabled(bEnabled);
+ node.write();
+ }
+ catch (jfw::FrameworkException& e)
+ {
+ errcode = e.errorCode;
+ fprintf(stderr, "%s\n", e.message.getStr());
+ OSL_FAIL(e.message.getStr());
+ }
+ return errcode;
+}
+
+javaFrameworkError SAL_CALL jfw_getEnabled(sal_Bool *pbEnabled)
+{
+ javaFrameworkError errcode = JFW_E_NONE;
+ try
+ {
+ if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
+ return JFW_E_DIRECT_MODE;
+ osl::MutexGuard guard(jfw::FwkMutex::get());
+ if (pbEnabled == NULL)
+ return JFW_E_INVALID_ARG;
+ jfw::MergedSettings settings;
+ *pbEnabled = settings.getEnabled();
+ }
+ catch (jfw::FrameworkException& e)
+ {
+ errcode = e.errorCode;
+ fprintf(stderr, "%s\n", e.message.getStr());
+ OSL_FAIL(e.message.getStr());
+ }
+ return errcode;
+}
+
+
+javaFrameworkError SAL_CALL jfw_setVMParameters(
+ rtl_uString * * arOptions, sal_Int32 nLen)
+{
+ javaFrameworkError errcode = JFW_E_NONE;
+ try
+ {
+ osl::MutexGuard guard(jfw::FwkMutex::get());
+ if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
+ return JFW_E_DIRECT_MODE;
+ jfw::NodeJava node;
+ if (arOptions == NULL && nLen != 0)
+ return JFW_E_INVALID_ARG;
+ node.setVmParameters(arOptions, nLen);
+ node.write();
+ }
+ catch (jfw::FrameworkException& e)
+ {
+ errcode = e.errorCode;
+ fprintf(stderr, "%s\n", e.message.getStr());
+ OSL_FAIL(e.message.getStr());
+ }
+
+ return errcode;
+}
+
+javaFrameworkError SAL_CALL jfw_getVMParameters(
+ rtl_uString *** parOptions, sal_Int32 * pLen)
+{
+ javaFrameworkError errcode = JFW_E_NONE;
+ try
+ {
+ osl::MutexGuard guard(jfw::FwkMutex::get());
+ if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
+ return JFW_E_DIRECT_MODE;
+
+ if (parOptions == NULL || pLen == NULL)
+ return JFW_E_INVALID_ARG;
+ const jfw::MergedSettings settings;
+ settings.getVmParametersArray(parOptions, pLen);
+ }
+ catch (jfw::FrameworkException& e)
+ {
+ errcode = e.errorCode;
+ fprintf(stderr, "%s\n", e.message.getStr());
+ OSL_FAIL(e.message.getStr());
+ }
+ return errcode;
+}
+
+javaFrameworkError SAL_CALL jfw_setUserClassPath(rtl_uString * pCp)
+{
+ javaFrameworkError errcode = JFW_E_NONE;
+ try
+ {
+ osl::MutexGuard guard(jfw::FwkMutex::get());
+ if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
+ return JFW_E_DIRECT_MODE;
+ jfw::NodeJava node;
+ if (pCp == NULL)
+ return JFW_E_INVALID_ARG;
+ node.setUserClassPath(pCp);
+ node.write();
+ }
+ catch (jfw::FrameworkException& e)
+ {
+ errcode = e.errorCode;
+ fprintf(stderr, "%s\n", e.message.getStr());
+ OSL_FAIL(e.message.getStr());
+ }
+ return errcode;
+}
+
+javaFrameworkError SAL_CALL jfw_getUserClassPath(rtl_uString ** ppCP)
+{
+ javaFrameworkError errcode = JFW_E_NONE;
+ try
+ {
+ osl::MutexGuard guard(jfw::FwkMutex::get());
+ if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
+ return JFW_E_DIRECT_MODE;
+ if (ppCP == NULL)
+ return JFW_E_INVALID_ARG;
+ const jfw::MergedSettings settings;
+ *ppCP = settings.getUserClassPath().pData;
+ rtl_uString_acquire(*ppCP);
+ }
+ catch (jfw::FrameworkException& e)
+ {
+ errcode = e.errorCode;
+ fprintf(stderr, "%s\n", e.message.getStr());
+ OSL_FAIL(e.message.getStr());
+ }
+ return errcode;
+}
+
+javaFrameworkError SAL_CALL jfw_addJRELocation(rtl_uString * sLocation)
+{
+ javaFrameworkError errcode = JFW_E_NONE;
+ try
+ {
+ osl::MutexGuard guard(jfw::FwkMutex::get());
+ if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
+ return JFW_E_DIRECT_MODE;
+ jfw::NodeJava node;
+ if (sLocation == NULL)
+ return JFW_E_INVALID_ARG;
+ node.load();
+ node.addJRELocation(sLocation);
+ node.write();
+ }
+ catch (jfw::FrameworkException& e)
+ {
+ errcode = e.errorCode;
+ fprintf(stderr, "%s\n", e.message.getStr());
+ OSL_FAIL(e.message.getStr());
+ }
+
+ return errcode;
+
+}
+
+javaFrameworkError SAL_CALL jfw_setJRELocations(
+ rtl_uString ** arLocations, sal_Int32 nLen)
+{
+ javaFrameworkError errcode = JFW_E_NONE;
+ try
+ {
+ osl::MutexGuard guard(jfw::FwkMutex::get());
+ if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
+ return JFW_E_DIRECT_MODE;
+ jfw::NodeJava node;
+ if (arLocations == NULL && nLen != 0)
+ return JFW_E_INVALID_ARG;
+ node.setJRELocations(arLocations, nLen);
+ node.write();
+ }
+ catch (jfw::FrameworkException& e)
+ {
+ errcode = e.errorCode;
+ fprintf(stderr, "%s\n", e.message.getStr());
+ OSL_FAIL(e.message.getStr());
+ }
+ return errcode;
+
+}
+
+javaFrameworkError SAL_CALL jfw_getJRELocations(
+ rtl_uString *** parLocations, sal_Int32 *pLen)
+{
+ javaFrameworkError errcode = JFW_E_NONE;
+ try
+ {
+ osl::MutexGuard guard(jfw::FwkMutex::get());
+ if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
+ return JFW_E_DIRECT_MODE;
+
+ if (parLocations == NULL || pLen == NULL)
+ return JFW_E_INVALID_ARG;
+ const jfw::MergedSettings settings;
+ settings.getJRELocations(parLocations, pLen);
+ }
+ catch (jfw::FrameworkException& e)
+ {
+ errcode = e.errorCode;
+ fprintf(stderr, "%s\n", e.message.getStr());
+ OSL_FAIL(e.message.getStr());
+ }
+
+ return errcode;
+}
+
+
+javaFrameworkError jfw_existJRE(const JavaInfo *pInfo, sal_Bool *exist)
+{
+ //get the function jfw_plugin_existJRE
+ jfw::VendorSettings aVendorSettings;
+ jfw::CJavaInfo aInfo;
+ aInfo = (const ::JavaInfo*) pInfo; //makes a copy of pInfo
+ rtl::OUString sLibPath = aVendorSettings.getPluginLibrary(aInfo.getVendor());
+ osl::Module modulePlugin(sLibPath);
+ if ( ! modulePlugin)
+ return JFW_E_NO_PLUGIN;
+ rtl::OUString sFunctionName(
+ RTL_CONSTASCII_USTRINGPARAM("jfw_plugin_existJRE"));
+ jfw_plugin_existJRE_ptr pFunc =
+ (jfw_plugin_existJRE_ptr)
+ osl_getFunctionSymbol(modulePlugin, sFunctionName.pData);
+ if (pFunc == NULL)
+ return JFW_E_ERROR;
+
+ javaPluginError plerr = (*pFunc)(pInfo, exist);
+
+ javaFrameworkError ret = JFW_E_NONE;
+ switch (plerr)
+ {
+ case JFW_PLUGIN_E_NONE:
+ ret = JFW_E_NONE;
+ break;
+ case JFW_PLUGIN_E_INVALID_ARG:
+ ret = JFW_E_INVALID_ARG;
+ break;
+ case JFW_PLUGIN_E_ERROR:
+ ret = JFW_E_ERROR;
+ break;
+ default:
+ ret = JFW_E_ERROR;
+ }
+ return ret;
+}
+
+void SAL_CALL jfw_lock()
+{
+ jfw::FwkMutex::get().acquire();
+}
+
+void SAL_CALL jfw_unlock()
+{
+ jfw::FwkMutex::get().release();
+}
+
+
+namespace jfw
+{
+CJavaInfo::CJavaInfo(): pInfo(0)
+{
+}
+
+CJavaInfo::CJavaInfo(const CJavaInfo & info)
+{
+ pInfo = copyJavaInfo(info.pInfo);
+}
+
+CJavaInfo::CJavaInfo(::JavaInfo * info, _transfer_ownership)
+{
+ pInfo = info;
+}
+CJavaInfo CJavaInfo::createWrapper(::JavaInfo* info)
+{
+ return CJavaInfo(info, TRANSFER);
+}
+void CJavaInfo::attach(::JavaInfo * info)
+{
+ jfw_freeJavaInfo(pInfo);
+ pInfo = info;
+}
+::JavaInfo * CJavaInfo::detach()
+{
+ JavaInfo * tmp = pInfo;
+ pInfo = NULL;
+ return tmp;
+}
+
+CJavaInfo::~CJavaInfo()
+{
+ jfw_freeJavaInfo(pInfo);
+}
+
+CJavaInfo::operator ::JavaInfo* ()
+{
+ return pInfo;
+}
+
+JavaInfo * CJavaInfo::copyJavaInfo(const JavaInfo * pInfo)
+{
+ if (pInfo == NULL)
+ return NULL;
+ JavaInfo* newInfo =
+ (JavaInfo*) rtl_allocateMemory(sizeof(JavaInfo));
+ if (newInfo)
+ {
+ rtl_copyMemory(newInfo, pInfo, sizeof(JavaInfo));
+ rtl_uString_acquire(pInfo->sVendor);
+ rtl_uString_acquire(pInfo->sLocation);
+ rtl_uString_acquire(pInfo->sVersion);
+ rtl_byte_sequence_acquire(pInfo->arVendorData);
+ }
+ return newInfo;
+}
+
+
+JavaInfo* CJavaInfo::cloneJavaInfo() const
+{
+ if (pInfo == NULL)
+ return NULL;
+ return copyJavaInfo(pInfo);
+}
+
+CJavaInfo & CJavaInfo::operator = (const CJavaInfo& info)
+{
+ if (&info == this)
+ return *this;
+
+ jfw_freeJavaInfo(pInfo);
+ pInfo = copyJavaInfo(info.pInfo);
+ return *this;
+}
+CJavaInfo & CJavaInfo::operator = (const ::JavaInfo* info)
+{
+ if (info == pInfo)
+ return *this;
+
+ jfw_freeJavaInfo(pInfo);
+ pInfo = copyJavaInfo(info);
+ return *this;
+}
+
+const ::JavaInfo* CJavaInfo::operator ->() const
+{
+ return pInfo;
+}
+
+CJavaInfo::operator JavaInfo const * () const
+{
+ return pInfo;
+}
+
+rtl::OUString CJavaInfo::getVendor() const
+{
+ if (pInfo)
+ return rtl::OUString(pInfo->sVendor);
+ else
+ return rtl::OUString();
+}
+
+rtl::OUString CJavaInfo::getLocation() const
+{
+ if (pInfo)
+ return rtl::OUString(pInfo->sLocation);
+ else
+ return rtl::OUString();
+}
+
+sal_uInt64 CJavaInfo::getFeatures() const
+{
+ if (pInfo)
+ return pInfo->nFeatures;
+ else
+ return 0l;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/jvmfwk/source/framework.hxx b/jvmfwk/source/framework.hxx
new file mode 100644
index 000000000000..0ba8c6b29583
--- /dev/null
+++ b/jvmfwk/source/framework.hxx
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#if !defined INCLUDED_JVMFWK_LOCAL_FRAMEWORK_HXX
+#define INCLUDED_JVMFWK_LOCAL_FRAMEWORK_HXX
+#include "rtl/ustring.hxx"
+#include "rtl/byteseq.hxx"
+#include "jvmfwk/framework.h"
+#include "jvmfwk/vendorplugin.h"
+
+/** typedefs for functions from vendorplugin.h
+ */
+typedef javaPluginError (*jfw_plugin_getAllJavaInfos_ptr)(
+ rtl_uString * sVendor,
+ rtl_uString * sMinVersion,
+ rtl_uString * sMaxVersion,
+ rtl_uString * * arExcludeList,
+ sal_Int32 nLenList,
+ JavaInfo*** parJavaInfo,
+ sal_Int32 *nLenInfoList);
+
+typedef javaPluginError (*jfw_plugin_getJavaInfoByPath_ptr)(
+ rtl_uString * sPath,
+ rtl_uString * sVendor,
+ rtl_uString * sMinVersion,
+ rtl_uString * sMaxVersion,
+ rtl_uString * * arExcludeList,
+ sal_Int32 nLenList,
+ JavaInfo** ppInfo);
+
+/** starts a Java Virtual Machine.
+ <p>
+ The function shall ensure, that the VM does not abort the process
+ during instantiation.
+ </p>
+ */
+typedef javaPluginError (*jfw_plugin_startJavaVirtualMachine_ptr)(
+ const JavaInfo *info,
+ const JavaVMOption* options,
+ sal_Int32 cOptions,
+ JavaVM ** ppVM,
+ JNIEnv ** ppEnv);
+
+typedef javaPluginError (*jfw_plugin_existJRE_ptr)(
+ const JavaInfo *info,
+ sal_Bool *exist);
+
+
+namespace jfw
+{
+
+class CJavaInfo
+{
+ static JavaInfo * copyJavaInfo(const JavaInfo * pInfo);
+
+ enum _transfer_ownership {TRANSFER};
+ /*Attaching the pointer to this class. The argument pInfo must not
+ be freed afterwards.
+ */
+ CJavaInfo(::JavaInfo * info, _transfer_ownership);
+
+public:
+ ::JavaInfo * pInfo;
+
+
+
+ CJavaInfo();
+ CJavaInfo(const CJavaInfo &);
+ ~CJavaInfo();
+ CJavaInfo& operator =(const ::JavaInfo* info);
+ CJavaInfo & operator = (const CJavaInfo& info);
+
+ /* The returned class takes ownership of the argument info. info
+ must not been freed afterwards.
+ */
+ static CJavaInfo createWrapper(::JavaInfo* info);
+ /*Attaching the pointer to this class. The argument pInfo must not
+ be freed afterwards.
+ */
+ void attach(::JavaInfo* pInfo);
+ ::JavaInfo * detach();
+ const ::JavaInfo* operator ->() const;
+ operator ::JavaInfo* ();
+ operator ::JavaInfo const * () const;
+ ::JavaInfo* cloneJavaInfo() const;
+
+ rtl::OUString getVendor() const;
+ rtl::OUString getLocation() const;
+ sal_uInt64 getFeatures() const;
+};
+
+class FrameworkException
+{
+public:
+
+ FrameworkException(javaFrameworkError err, const rtl::OString& msg):
+ errorCode(err), message(msg)
+ {
+ }
+ javaFrameworkError errorCode;
+ rtl::OString message;
+};
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/jvmfwk/source/framework.map b/jvmfwk/source/framework.map
new file mode 100644
index 000000000000..c95cc83aa826
--- /dev/null
+++ b/jvmfwk/source/framework.map
@@ -0,0 +1,31 @@
+UDK_3_0_0 {
+ global:
+ # jvmfwk/framework.h:
+ jfw_freeJavaInfo;
+ jfw_areEqualJavaInfo;
+ jfw_findAllJREs;
+ jfw_findAndSelectJRE;
+ jfw_startVM;
+ jfw_isVMRunning;
+ jfw_getJavaInfoByPath;
+ jfw_setSelectedJRE;
+ jfw_getSelectedJRE;
+ jfw_setEnabled;
+ jfw_getEnabled;
+ jfw_setVMParameters;
+ jfw_getVMParameters;
+ jfw_setUserClassPath;
+ jfw_getUserClassPath;
+ jfw_setJRELocations;
+ jfw_getJRELocations;
+ jfw_addJRELocation;
+ jfw_lock;
+ jfw_unlock;
+ local:
+ *;
+};
+
+UDK_3.1 { # OOo 3.1.0
+ global:
+ jfw_existJRE;
+} UDK_3_0_0;
diff --git a/jvmfwk/source/fwkbase.cxx b/jvmfwk/source/fwkbase.cxx
new file mode 100644
index 000000000000..3b3f4087e610
--- /dev/null
+++ b/jvmfwk/source/fwkbase.cxx
@@ -0,0 +1,726 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_jvmfwk.hxx"
+#include "rtl/ustring.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/uri.hxx"
+#include "osl/thread.hxx"
+#include "osl/process.h"
+#include "libxml/xpathInternals.h"
+#include "osl/file.hxx"
+#include "osl/module.hxx"
+#include "framework.hxx"
+#include "fwkutil.hxx"
+#include "elements.hxx"
+#include "fwkbase.hxx"
+
+using namespace osl;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::rtl::OString;
+using ::rtl::OUStringToOString;
+using ::rtl::OStringToOUString;
+#define JAVASETTINGS "javasettings"
+#define JAVASETTINGS_XML "javasettings.xml"
+#define VENDORSETTINGS "javavendors.xml"
+
+#define UNO_JAVA_JFW_PARAMETER "UNO_JAVA_JFW_PARAMETER_"
+#define UNO_JAVA_JFW_JREHOME "UNO_JAVA_JFW_JREHOME"
+#define UNO_JAVA_JFW_ENV_JREHOME "UNO_JAVA_JFW_ENV_JREHOME"
+#define UNO_JAVA_JFW_CLASSPATH "UNO_JAVA_JFW_CLASSPATH"
+#define UNO_JAVA_JFW_ENV_CLASSPATH "UNO_JAVA_JFW_ENV_CLASSPATH"
+#define UNO_JAVA_JFW_CLASSPATH_URLS "UNO_JAVA_JFW_CLASSPATH_URLS"
+#define UNO_JAVA_JFW_PARAMETERS "UNO_JAVA_JFW_PARAMETERS"
+#define UNO_JAVA_JFW_VENDOR_SETTINGS "UNO_JAVA_JFW_VENDOR_SETTINGS"
+#define UNO_JAVA_JFW_USER_DATA "UNO_JAVA_JFW_USER_DATA"
+#define UNO_JAVA_JFW_SHARED_DATA "UNO_JAVA_JFW_SHARED_DATA"
+#define UNO_JAVA_JFW_INSTALL_DATA "UNO_JAVA_JFW_INSTALL_DATA"
+#define UNO_JAVA_JFW_INSTALL_EXPIRE "UNO_JAVA_JFW_INSTALL_EXPIRE"
+#define DEFAULT_INSTALL_EXPIRATION 3600
+
+namespace jfw
+{
+bool g_bJavaSet = false;
+
+namespace {
+
+rtl::OString getVendorSettingsPath(rtl::OUString const & sURL)
+{
+ if (sURL.getLength() == 0)
+ return rtl::OString();
+ rtl::OUString sSystemPathSettings;
+ if (osl_getSystemPathFromFileURL(sURL.pData,
+ & sSystemPathSettings.pData) != osl_File_E_None)
+ throw FrameworkException(
+ JFW_E_ERROR,
+ rtl::OString("[Java framework] Error in function "
+ "getVendorSettingsPath (fwkbase.cxx) "));
+ rtl::OString osSystemPathSettings =
+ rtl::OUStringToOString(sSystemPathSettings,osl_getThreadTextEncoding());
+ return osSystemPathSettings;
+}
+
+rtl::OUString getParam(const char * name)
+{
+ rtl::OUString retVal;
+ if (Bootstrap::get()->getFrom(rtl::OUString::createFromAscii(name), retVal))
+ {
+#if OSL_DEBUG_LEVEL >=2
+ rtl::OString sValue = rtl::OUStringToOString(retVal, osl_getThreadTextEncoding());
+ fprintf(stderr,"[Java framework] Using bootstrap parameter %s = %s.\n",
+ name, sValue.getStr());
+#endif
+ }
+ return retVal;
+}
+
+rtl::OUString getParamFirstUrl(const char * name)
+{
+ // Some parameters can consist of multiple URLs (separated by space
+ // characters, although trim() harmlessly also removes other white-space),
+ // of which only the first is used:
+ sal_Int32 i = 0;
+ return getParam(name).trim().getToken(0, ' ', i);
+}
+
+}//blind namespace
+
+
+VendorSettings::VendorSettings():
+ m_xmlDocVendorSettingsFileUrl(BootParams::getVendorSettings())
+{
+ OString sMsgExc("[Java framework] Error in constructor "
+ "VendorSettings::VendorSettings() (fwkbase.cxx)");
+ //Prepare the xml document and context
+ OString sSettingsPath = getVendorSettingsPath(m_xmlDocVendorSettingsFileUrl);
+ if (sSettingsPath.getLength() == 0)
+ {
+ OString sMsg("[Java framework] A vendor settings file was not specified."
+ "Check the bootstrap parameter " UNO_JAVA_JFW_VENDOR_SETTINGS ".");
+ OSL_FAIL(sMsg.getStr());
+ throw FrameworkException(JFW_E_CONFIGURATION, sMsg);
+ }
+ if (sSettingsPath.getLength() > 0)
+ {
+ m_xmlDocVendorSettings = xmlParseFile(sSettingsPath.getStr());
+ if (m_xmlDocVendorSettings == NULL)
+ throw FrameworkException(
+ JFW_E_ERROR,
+ OString("[Java framework] Error while parsing file: ")
+ + sSettingsPath + OString("."));
+
+ m_xmlPathContextVendorSettings = xmlXPathNewContext(m_xmlDocVendorSettings);
+ int res = xmlXPathRegisterNs(
+ m_xmlPathContextVendorSettings, (xmlChar*) "jf",
+ (xmlChar*) NS_JAVA_FRAMEWORK);
+ if (res == -1)
+ throw FrameworkException(JFW_E_ERROR, sMsgExc);
+ }
+}
+
+std::vector<PluginLibrary> VendorSettings::getPluginData()
+{
+ OString sExcMsg("[Java framework] Error in function VendorSettings::getVendorPluginURLs "
+ "(fwkbase.cxx).");
+ std::vector<PluginLibrary> vecPlugins;
+ CXPathObjectPtr result(xmlXPathEvalExpression(
+ (xmlChar*)"/jf:javaSelection/jf:plugins/jf:library",
+ m_xmlPathContextVendorSettings));
+ if (xmlXPathNodeSetIsEmpty(result->nodesetval))
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ //get the values of the library elements + vendor attribute
+ xmlNode* cur = result->nodesetval->nodeTab[0];
+
+ while (cur != NULL)
+ {
+ //between library elements are also text elements
+ if (cur->type == XML_ELEMENT_NODE)
+ {
+ CXmlCharPtr sAttrVendor(xmlGetProp(cur, (xmlChar*) "vendor"));
+ CXmlCharPtr sTextLibrary(
+ xmlNodeListGetString(m_xmlDocVendorSettings,
+ cur->xmlChildrenNode, 1));
+ PluginLibrary plugin;
+ OString osVendor((sal_Char*)(xmlChar*) sAttrVendor);
+ plugin.sVendor = OStringToOUString(osVendor, RTL_TEXTENCODING_UTF8);
+
+ //create the file URL to the library
+ OUString sUrl = findPlugin(
+ m_xmlDocVendorSettingsFileUrl, sTextLibrary);
+ if (sUrl.getLength() == 0)
+ {
+ OString sPlugin = OUStringToOString(
+ sTextLibrary, osl_getThreadTextEncoding());
+ throw FrameworkException(
+ JFW_E_CONFIGURATION,
+ "[Java framework] The file: " + sPlugin + " does not exist.");
+ }
+ plugin.sPath = sUrl;
+
+ vecPlugins.push_back(plugin);
+ }
+ cur = cur->next;
+ }
+ return vecPlugins;
+}
+
+VersionInfo VendorSettings::getVersionInformation(const rtl::OUString & sVendor)
+{
+ OSL_ASSERT(sVendor.getLength() > 0);
+ VersionInfo aVersionInfo;
+ OString osVendor = OUStringToOString(sVendor, RTL_TEXTENCODING_UTF8);
+ //Get minVersion
+ OString sExpresion = OString(
+ "/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"") +
+ osVendor + OString("\"]/jf:minVersion");
+
+ CXPathObjectPtr xPathObjectMin;
+ xPathObjectMin =
+ xmlXPathEvalExpression((xmlChar*) sExpresion.getStr(),
+ m_xmlPathContextVendorSettings);
+ if (xmlXPathNodeSetIsEmpty(xPathObjectMin->nodesetval))
+ {
+ aVersionInfo.sMinVersion = OUString();
+ }
+ else
+ {
+ CXmlCharPtr sVersion;
+ sVersion = xmlNodeListGetString(
+ m_xmlDocVendorSettings,
+ xPathObjectMin->nodesetval->nodeTab[0]->xmlChildrenNode, 1);
+ OString osVersion((sal_Char*)(xmlChar*) sVersion);
+ aVersionInfo.sMinVersion = OStringToOUString(
+ osVersion, RTL_TEXTENCODING_UTF8);
+ }
+
+ //Get maxVersion
+ sExpresion = OString("/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"") +
+ osVendor + OString("\"]/jf:maxVersion");
+ CXPathObjectPtr xPathObjectMax;
+ xPathObjectMax = xmlXPathEvalExpression(
+ (xmlChar*) sExpresion.getStr(),
+ m_xmlPathContextVendorSettings);
+ if (xmlXPathNodeSetIsEmpty(xPathObjectMax->nodesetval))
+ {
+ aVersionInfo.sMaxVersion = OUString();
+ }
+ else
+ {
+ CXmlCharPtr sVersion;
+ sVersion = xmlNodeListGetString(
+ m_xmlDocVendorSettings,
+ xPathObjectMax->nodesetval->nodeTab[0]->xmlChildrenNode, 1);
+ OString osVersion((sal_Char*) (xmlChar*) sVersion);
+ aVersionInfo.sMaxVersion = OStringToOUString(
+ osVersion, RTL_TEXTENCODING_UTF8);
+ }
+
+ //Get excludeVersions
+ sExpresion = OString("/jf:javaSelection/jf:vendorInfos/jf:vendor[@name=\"") +
+ osVendor + OString("\"]/jf:excludeVersions/jf:version");
+ CXPathObjectPtr xPathObjectVersions;
+ xPathObjectVersions =
+ xmlXPathEvalExpression((xmlChar*) sExpresion.getStr(),
+ m_xmlPathContextVendorSettings);
+ if (!xmlXPathNodeSetIsEmpty(xPathObjectVersions->nodesetval))
+ {
+ xmlNode* cur = xPathObjectVersions->nodesetval->nodeTab[0];
+ while (cur != NULL)
+ {
+ if (cur->type == XML_ELEMENT_NODE )
+ {
+ if (xmlStrcmp(cur->name, (xmlChar*) "version") == 0)
+ {
+ CXmlCharPtr sVersion;
+ sVersion = xmlNodeListGetString(
+ m_xmlDocVendorSettings, cur->xmlChildrenNode, 1);
+ OString osVersion((sal_Char*)(xmlChar*) sVersion);
+ OUString usVersion = OStringToOUString(
+ osVersion, RTL_TEXTENCODING_UTF8);
+ aVersionInfo.addExcludeVersion(usVersion);
+ }
+ }
+ cur = cur->next;
+ }
+ }
+ return aVersionInfo;
+}
+
+std::vector<OUString> VendorSettings::getSupportedVendors()
+{
+ std::vector<rtl::OUString> vecVendors;
+ //get the nodeset for the library elements
+ jfw::CXPathObjectPtr result;
+ result = xmlXPathEvalExpression(
+ (xmlChar*)"/jf:javaSelection/jf:plugins/jf:library",
+ m_xmlPathContextVendorSettings);
+ if (xmlXPathNodeSetIsEmpty(result->nodesetval))
+ throw FrameworkException(
+ JFW_E_ERROR,
+ rtl::OString("[Java framework] Error in function getSupportedVendors (fwkbase.cxx)."));
+
+ //get the values of the library elements + vendor attribute
+ xmlNode* cur = result->nodesetval->nodeTab[0];
+ while (cur != NULL)
+ {
+ //between library elements are also text elements
+ if (cur->type == XML_ELEMENT_NODE)
+ {
+ jfw::CXmlCharPtr sAttrVendor(xmlGetProp(cur, (xmlChar*) "vendor"));
+ vecVendors.push_back(sAttrVendor);
+ }
+ cur = cur->next;
+ }
+ return vecVendors;
+}
+
+OUString VendorSettings::getPluginLibrary(const OUString& sVendor)
+{
+ OSL_ASSERT(sVendor.getLength() > 0);
+
+ OString sExcMsg("[Java framework] Error in function getPluginLibrary (fwkbase.cxx).");
+ OString sVendorsPath = getVendorSettingsPath(m_xmlDocVendorSettingsFileUrl);
+ OUStringBuffer usBuffer(256);
+ usBuffer.appendAscii("/jf:javaSelection/jf:plugins/jf:library[@vendor=\"");
+ usBuffer.append(sVendor);
+ usBuffer.appendAscii("\"]/text()");
+ OUString ouExpr = usBuffer.makeStringAndClear();
+ OString sExpression =
+ OUStringToOString(ouExpr, osl_getThreadTextEncoding());
+ CXPathObjectPtr pathObjVendor;
+ pathObjVendor = xmlXPathEvalExpression(
+ (xmlChar*) sExpression.getStr(), m_xmlPathContextVendorSettings);
+ if (xmlXPathNodeSetIsEmpty(pathObjVendor->nodesetval))
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ CXmlCharPtr xmlCharPlugin;
+ xmlCharPlugin =
+ xmlNodeListGetString(
+ m_xmlDocVendorSettings,pathObjVendor->nodesetval->nodeTab[0], 1);
+
+ //make an absolute file url from the relative plugin URL
+ OUString sUrl = findPlugin(m_xmlDocVendorSettingsFileUrl, xmlCharPlugin);
+ if (sUrl.getLength() == 0)
+ {
+ OString sPlugin = OUStringToOString(
+ xmlCharPlugin, osl_getThreadTextEncoding());
+ throw FrameworkException(
+ JFW_E_CONFIGURATION,
+ "[Java framework] The file: " + sPlugin + " does not exist.");
+ }
+ return sUrl;
+}
+
+::std::vector<OString> BootParams::getVMParameters()
+{
+ ::std::vector<OString> vecParams;
+
+ for (sal_Int32 i = 1; ; i++)
+ {
+ OUString sName =
+ OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_PARAMETER)) +
+ OUString::valueOf(i);
+ OUString sValue;
+ if (Bootstrap::get()->getFrom(sName, sValue) == sal_True)
+ {
+ OString sParam =
+ OUStringToOString(sValue, osl_getThreadTextEncoding());
+ vecParams.push_back(sParam);
+#if OSL_DEBUG_LEVEL >=2
+ rtl::OString sParamName = rtl::OUStringToOString(sName, osl_getThreadTextEncoding());
+ fprintf(stderr,"[Java framework] Using bootstrap parameter %s"
+ " = %s.\n", sParamName.getStr(), sParam.getStr());
+#endif
+ }
+ else
+ break;
+ }
+ return vecParams;
+}
+
+rtl::OUString BootParams::getUserData()
+{
+ return getParamFirstUrl(UNO_JAVA_JFW_USER_DATA);
+}
+
+rtl::OUString BootParams::getSharedData()
+{
+ return getParamFirstUrl(UNO_JAVA_JFW_SHARED_DATA);
+}
+
+rtl::OUString BootParams::getInstallData()
+{
+ return getParam(UNO_JAVA_JFW_INSTALL_DATA);
+}
+
+
+rtl::OString BootParams::getClasspath()
+{
+ rtl::OString sClassPath;
+ rtl::OUString sCP;
+ char szSep[] = {SAL_PATHSEPARATOR,0};
+ if (Bootstrap::get()->getFrom(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_CLASSPATH)),
+ sCP) == sal_True)
+ {
+ sClassPath = rtl::OUStringToOString(
+ sCP, osl_getThreadTextEncoding());
+#if OSL_DEBUG_LEVEL >=2
+ fprintf(stderr,"[Java framework] Using bootstrap parameter "
+ UNO_JAVA_JFW_CLASSPATH " = %s.\n", sClassPath.getStr());
+#endif
+ }
+
+ rtl::OUString sEnvCP;
+ if (Bootstrap::get()->getFrom(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_ENV_CLASSPATH)),
+ sEnvCP) == sal_True)
+ {
+ char * pCp = getenv("CLASSPATH");
+ if (pCp)
+ {
+ sClassPath += rtl::OString(szSep) + rtl::OString(pCp);
+ }
+#if OSL_DEBUG_LEVEL >=2
+ fprintf(stderr,"[Java framework] Using bootstrap parameter "
+ UNO_JAVA_JFW_ENV_CLASSPATH " and class path is:\n %s.\n", pCp ? pCp : "");
+#endif
+ }
+
+ return sClassPath;
+}
+
+rtl::OUString BootParams::getVendorSettings()
+{
+ rtl::OUString sVendor;
+ rtl::OUString sName(
+ RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_VENDOR_SETTINGS));
+ if (Bootstrap::get()->getFrom(sName ,sVendor) == sal_True)
+ {
+ //check the value of the bootstrap variable
+ jfw::FileStatus s = checkFileURL(sVendor);
+ if (s != FILE_OK)
+ {
+ //This bootstrap parameter can contain a relative URL
+ rtl::OUString sAbsoluteUrl;
+ rtl::OUString sBaseDir = getLibraryLocation();
+ if (File::getAbsoluteFileURL(sBaseDir, sVendor, sAbsoluteUrl)
+ != File::E_None)
+ throw FrameworkException(
+ JFW_E_CONFIGURATION,
+ rtl::OString("[Java framework] Invalid value for bootstrap variable: "
+ UNO_JAVA_JFW_VENDOR_SETTINGS));
+ sVendor = sAbsoluteUrl;
+ s = checkFileURL(sVendor);
+ if (s == jfw::FILE_INVALID || s == jfw::FILE_DOES_NOT_EXIST)
+ {
+ throw FrameworkException(
+ JFW_E_CONFIGURATION,
+ rtl::OString("[Java framework] Invalid value for bootstrap variable: "
+ UNO_JAVA_JFW_VENDOR_SETTINGS));
+ }
+ }
+#if OSL_DEBUG_LEVEL >=2
+ rtl::OString sValue = rtl::OUStringToOString(sVendor, osl_getThreadTextEncoding());
+ fprintf(stderr,"[Java framework] Using bootstrap parameter "
+ UNO_JAVA_JFW_VENDOR_SETTINGS" = %s.\n", sValue.getStr());
+#endif
+ }
+ return sVendor;
+}
+
+rtl::OUString BootParams::getJREHome()
+{
+ rtl::OUString sJRE;
+ rtl::OUString sEnvJRE;
+ sal_Bool bJRE = Bootstrap::get()->getFrom(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_JREHOME)) ,sJRE);
+ sal_Bool bEnvJRE = Bootstrap::get()->getFrom(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_ENV_JREHOME)) ,sEnvJRE);
+
+ if (bJRE == sal_True && bEnvJRE == sal_True)
+ {
+ throw FrameworkException(
+ JFW_E_CONFIGURATION,
+ rtl::OString("[Java framework] Both bootstrap parameter "
+ UNO_JAVA_JFW_JREHOME" and "
+ UNO_JAVA_JFW_ENV_JREHOME" are set. However only one of them can be set."
+ "Check bootstrap parameters: environment variables, command line "
+ "arguments, rc/ini files for executable and java framework library."));
+ }
+ else if (bEnvJRE == sal_True)
+ {
+ const char * pJRE = getenv("JAVA_HOME");
+ if (pJRE == NULL)
+ {
+ throw FrameworkException(
+ JFW_E_CONFIGURATION,
+ rtl::OString("[Java framework] Both bootstrap parameter "
+ UNO_JAVA_JFW_ENV_JREHOME" is set, but the environment variable "
+ "JAVA_HOME is not set."));
+ }
+ rtl::OString osJRE(pJRE);
+ rtl::OUString usJRE = rtl::OStringToOUString(osJRE, osl_getThreadTextEncoding());
+ if (File::getFileURLFromSystemPath(usJRE, sJRE) != File::E_None)
+ throw FrameworkException(
+ JFW_E_ERROR,
+ rtl::OString("[Java framework] Error in function BootParams::getJREHome() "
+ "(fwkbase.cxx)."));
+#if OSL_DEBUG_LEVEL >=2
+ fprintf(stderr,"[Java framework] Using bootstrap parameter "
+ UNO_JAVA_JFW_ENV_JREHOME" with JAVA_HOME = %s.\n", pJRE);
+#endif
+ }
+ else if (getMode() == JFW_MODE_DIRECT
+ && bEnvJRE == sal_False
+ && bJRE == sal_False)
+ {
+ throw FrameworkException(
+ JFW_E_CONFIGURATION,
+ rtl::OString("[Java framework] The bootstrap parameter "
+ UNO_JAVA_JFW_ENV_JREHOME" or " UNO_JAVA_JFW_JREHOME
+ " must be set in direct mode."));
+ }
+
+#if OSL_DEBUG_LEVEL >=2
+ if (bJRE == sal_True)
+ {
+ rtl::OString sValue = rtl::OUStringToOString(sJRE, osl_getThreadTextEncoding());
+ fprintf(stderr,"[Java framework] Using bootstrap parameter "
+ UNO_JAVA_JFW_JREHOME" = %s.\n", sValue.getStr());
+ }
+#endif
+ return sJRE;
+}
+
+rtl::OUString BootParams::getClasspathUrls()
+{
+ rtl::OUString sParams;
+ Bootstrap::get()->getFrom(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_CLASSPATH_URLS)),
+ sParams);
+#if OSL_DEBUG_LEVEL >=2
+ rtl::OString sValue = rtl::OUStringToOString(sParams, osl_getThreadTextEncoding());
+ fprintf(stderr,"[Java framework] Using bootstrap parameter "
+ UNO_JAVA_JFW_CLASSPATH_URLS " = %s.\n", sValue.getStr());
+#endif
+ return sParams;
+}
+
+::sal_uInt32 BootParams::getInstallDataExpiration()
+{
+ rtl::OUString sValue;
+ Bootstrap::get()->getFrom(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_INSTALL_EXPIRE)),
+ sValue);
+
+#if OSL_DEBUG_LEVEL >=2
+ rtl::OString osValue = rtl::OUStringToOString(sValue, osl_getThreadTextEncoding());
+ fprintf(stderr,"[Java framework] Using bootstrap parameter "
+ UNO_JAVA_JFW_INSTALL_EXPIRE " = %s.\n", osValue.getStr());
+#endif
+
+ sal_Int64 nVal = sValue.toInt64();
+ if (0 == nVal)
+ {
+#if OSL_DEBUG_LEVEL >=2
+ fprintf(stderr,"[Java framework] Using default value for "
+ "UNO_JAVA_JFW_INSTALL_EXPIRE: %d \n", DEFAULT_INSTALL_EXPIRATION);
+#endif
+ return DEFAULT_INSTALL_EXPIRATION;
+ }
+ else
+ {
+ return static_cast<sal_uInt32>(nVal);
+ }
+}
+
+JFW_MODE getMode()
+{
+ static bool g_bMode = false;
+ static JFW_MODE g_mode = JFW_MODE_APPLICATION;
+
+ if (g_bMode == false)
+ {
+ //check if either of the "direct mode" bootstrap variables is set
+ bool bDirectMode = true;
+ rtl::OUString sValue;
+ const rtl::Bootstrap * aBoot = Bootstrap::get();
+ rtl::OUString sJREHome(
+ RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_JREHOME));
+ if (aBoot->getFrom(sJREHome, sValue) == sal_False)
+ {
+ rtl::OUString sEnvJRE(
+ RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_ENV_JREHOME));
+ if (aBoot->getFrom(sEnvJRE, sValue) == sal_False)
+ {
+ rtl::OUString sClasspath(
+ RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_CLASSPATH));
+ if (aBoot->getFrom(sClasspath, sValue) == sal_False)
+ {
+ rtl::OUString sEnvClasspath(
+ RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_ENV_CLASSPATH));
+ if (aBoot->getFrom(sEnvClasspath, sValue) == sal_False)
+ {
+ rtl::OUString sParams = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(UNO_JAVA_JFW_PARAMETER)) +
+ rtl::OUString::valueOf((sal_Int32)1);
+ if (aBoot->getFrom(sParams, sValue) == sal_False)
+ {
+ bDirectMode = false;
+ }
+ }
+ }
+ }
+ }
+
+ if (bDirectMode)
+ g_mode = JFW_MODE_DIRECT;
+ else
+ g_mode = JFW_MODE_APPLICATION;
+ g_bMode = true;
+ }
+
+ return g_mode;
+}
+
+rtl::OUString getApplicationClassPath()
+{
+ OSL_ASSERT(getMode() == JFW_MODE_APPLICATION);
+ rtl::OUString retVal;
+ rtl::OUString sParams = BootParams::getClasspathUrls();
+ if (sParams.getLength() == 0)
+ return retVal;
+
+ rtl::OUStringBuffer buf;
+ sal_Int32 index = 0;
+ char szClassPathSep[] = {SAL_PATHSEPARATOR,0};
+ do
+ {
+ ::rtl::OUString token( sParams.getToken( 0, ' ', index ).trim() );
+ if (token.getLength())
+ {
+ ::rtl::OUString systemPathElement;
+ oslFileError rc = osl_getSystemPathFromFileURL(
+ token.pData, &systemPathElement.pData );
+ OSL_ASSERT( rc == osl_File_E_None );
+ if (rc == osl_File_E_None && systemPathElement.getLength() > 0)
+ {
+ if (buf.getLength() > 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ szClassPathSep) );
+ buf.append( systemPathElement );
+ }
+ }
+ }
+ while (index >= 0);
+ return buf.makeStringAndClear();
+}
+
+rtl::OString makeClassPathOption(OUString const & sUserClassPath)
+{
+ //Compose the class path
+ rtl::OString sPaths;
+ rtl::OUStringBuffer sBufCP(4096);
+ char szSep[] = {SAL_PATHSEPARATOR,0};
+
+ // append all user selected jars to the class path
+ if (sUserClassPath.getLength() > 0)
+ sBufCP.append(sUserClassPath);
+
+ //append all jar libraries and components to the class path
+ OUString sAppCP = getApplicationClassPath();
+ if (sAppCP.getLength())
+ {
+ if (sUserClassPath.getLength())
+ sBufCP.appendAscii(szSep);
+ sBufCP.append(sAppCP);
+ }
+
+ sPaths = rtl::OUStringToOString(
+ sBufCP.makeStringAndClear(), osl_getThreadTextEncoding());
+
+ rtl::OString sOptionClassPath("-Djava.class.path=");
+ sOptionClassPath += sPaths;
+ return sOptionClassPath;
+}
+
+rtl::OString getUserSettingsPath()
+{
+ return getSettingsPath(BootParams::getUserData());
+}
+
+rtl::OString getSharedSettingsPath()
+{
+ return getSettingsPath(BootParams::getSharedData());
+}
+
+rtl::OString getInstallSettingsPath()
+{
+ return getSettingsPath(BootParams::getInstallData());
+}
+
+rtl::OString getSettingsPath( const rtl::OUString & sURL)
+{
+ if (sURL.getLength() == 0)
+ return rtl::OString();
+ rtl::OUString sPath;
+ if (osl_getSystemPathFromFileURL(sURL.pData,
+ & sPath.pData) != osl_File_E_None)
+ throw FrameworkException(
+ JFW_E_ERROR, rtl::OString(
+ "[Java framework] Error in function ::getSettingsPath (fwkbase.cxx)."));
+ return rtl::OUStringToOString(sPath,osl_getThreadTextEncoding());
+}
+
+rtl::OString getVendorSettingsPath()
+{
+ return getVendorSettingsPath(BootParams::getVendorSettings());
+}
+
+void setJavaSelected()
+{
+ g_bJavaSet = true;
+}
+
+bool wasJavaSelectedInSameProcess()
+{
+ //g_setJavaProcId not set means no Java selected
+ if (g_bJavaSet == true)
+ return true;
+ return false;
+}
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/jvmfwk/source/fwkbase.hxx b/jvmfwk/source/fwkbase.hxx
new file mode 100644
index 000000000000..0a15f7628e8e
--- /dev/null
+++ b/jvmfwk/source/fwkbase.hxx
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#if !defined INCLUDED_JVMFWK_FWKBASE_HXX
+#define INCLUDED_JVMFWK_FWKBASE_HXX
+#include "rtl/ustring.hxx"
+#include "libxmlutil.hxx"
+namespace jfw
+{
+
+class VendorSettings
+{
+ ::rtl::OUString m_xmlDocVendorSettingsFileUrl;
+ CXmlDocPtr m_xmlDocVendorSettings;
+ CXPathContextPtr m_xmlPathContextVendorSettings;
+
+public:
+ VendorSettings();
+
+ /** Gets all plugin library URLs with the corresponding vendor name.
+
+ It uses the /javaSelection/plugins/library element from the javavendors.xml
+ to locate the library.
+ Is is verified that the plug-in exist. If a plug-in does not exist then an
+ exception is thrown containing the error JFW_E_CONFIGURATION
+ */
+ ::std::vector<PluginLibrary> getPluginData();
+
+ /* returns the file URL to the plugin.
+ */
+ ::rtl::OUString getPluginLibrary(const ::rtl::OUString& sVendor);
+
+ VersionInfo getVersionInformation(const ::rtl::OUString & sVendor);
+
+ ::std::vector< ::rtl::OUString> getSupportedVendors();
+};
+
+/* The class offers functions to retrieve verified bootstrap parameters.
+ */
+namespace BootParams
+{
+
+/* Gets the file URL to the JRE which has been determined by the
+ bootstrap parameter UNO_JAVA_JFW_JREHOME or UNO_JAVA_JFW_ENV_JREHOME.
+
+ In direct mode either of them must be set. If not an exception is thrown.
+*/
+::rtl::OUString getJREHome();
+
+::std::vector< ::rtl::OString> getVMParameters();
+
+::rtl::OUString getUserData();
+
+::rtl::OUString getSharedData();
+
+::rtl::OUString getInstallData();
+/* returns the file URL to the vendor settings xml file.
+ */
+::rtl::OUString getVendorSettings();
+
+/* User the parameter UNO_JAVA_JFW_CLASSPATH and UNO_JAVA_JFW_ENV_CLASSPATH
+ to compose a classpath
+ */
+::rtl::OString getClasspath();
+
+::rtl::OUString getClasspathUrls();
+
+/** returns the content of UNO_JAVA_JFW_INSTALL_EXPIRE or a pretermined
+ value. If the bootstrap variable contains a string that cannot be
+ converted by OUString then it returns the predetermined value.
+*/
+::sal_uInt32 getInstallDataExpiration();
+
+} //end namespace
+
+
+
+enum JFW_MODE
+{
+ JFW_MODE_APPLICATION,
+
+ JFW_MODE_DIRECT
+};
+
+JFW_MODE getMode();
+
+/** creates the -Djava.class.path option with the complete classpath, including
+ the paths which are set by UNO_JAVA_JFW_CLASSPATH_URLS.
+ */
+::rtl::OString makeClassPathOption(::rtl::OUString const & sUserClassPath);
+
+::rtl::OString getSettingsPath( const ::rtl::OUString & sURL);
+
+/** Get the system path to the javasettings.xml
+ Converts the URL returned from getUserSettingsURL to a
+ Systempath. An empty string is returned if the file
+ does not exist.
+ @throws FrameworkException
+ */
+::rtl::OString getUserSettingsPath();
+
+::rtl::OString getInstallSettingsPath();
+
+/** Returns the system path of the share settings file.
+ Returns a valid string or throws an exception.
+ @throws FrameworkException
+ */
+::rtl::OString getSharedSettingsPath();
+
+/* returns a valid string or throws an exception.
+ @throws FrameworkException
+ */
+::rtl::OString getVendorSettingsPath();
+
+::rtl::OUString buildClassPathFromDirectory(const ::rtl::OUString & relPath);
+
+/** Called from writeJavaInfoData. It sets the process identifier. When
+java is to be started, then the current id is compared to the one set by
+this function. If they are identical then the Java was selected in the
+same process. If that Java needs a prepared environment, such as a
+LD_LIBRARY_PATH, then it must not be started in this process.
+*/
+void setJavaSelected();
+
+/** Determines if the currently selected Java was set in this process.
+
+ @see setProcessId()
+ */
+bool wasJavaSelectedInSameProcess();
+/* Only for application mode.
+ */
+::rtl::OUString getApplicationClassPath();
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/jvmfwk/source/fwkutil.cxx b/jvmfwk/source/fwkutil.cxx
new file mode 100644
index 000000000000..3b73534e129e
--- /dev/null
+++ b/jvmfwk/source/fwkutil.cxx
@@ -0,0 +1,362 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_jvmfwk.hxx"
+
+#if defined WNT
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#endif
+#include <windows.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#endif
+
+#include <string>
+#include <string.h>
+#include "osl/mutex.hxx"
+#include "osl/module.hxx"
+#include "osl/thread.hxx"
+#include "rtl/ustring.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/bootstrap.hxx"
+#include "osl/file.hxx"
+#include "osl/process.h"
+#include "rtl/instance.hxx"
+#include "rtl/uri.hxx"
+#include "osl/getglobalmutex.hxx"
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
+#include "cppuhelper/bootstrap.hxx"
+
+#include "framework.hxx"
+#include "fwkutil.hxx"
+
+using namespace osl;
+
+using ::rtl::OUString;
+using ::rtl::OUStringToOString;
+using ::rtl::OString;
+
+namespace jfw
+{
+
+bool isAccessibilitySupportDesired()
+{
+ OUString sValue;
+ if ((sal_True == ::rtl::Bootstrap::get(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY")), sValue))
+ && sValue.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("1")))
+ )
+ return false;
+
+ bool retVal = false;
+#ifdef WNT
+ HKEY hKey = 0;
+ if (RegOpenKeyEx(HKEY_CURRENT_USER,
+ "Software\\OpenOffice.org\\Accessibility\\AtToolSupport",
+ 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+ {
+ DWORD dwType = 0;
+ DWORD dwLen = 16;
+ unsigned char arData[16];
+ if( RegQueryValueEx(hKey, "SupportAssistiveTechnology", NULL, &dwType, arData,
+ & dwLen)== ERROR_SUCCESS)
+ {
+ if (dwType == REG_SZ)
+ {
+ if (strcmp((char*) arData, "true") == 0
+ || strcmp((char*) arData, "1") == 0)
+ retVal = true;
+ else if (strcmp((char*) arData, "false") == 0
+ || strcmp((char*) arData, "0") == 0)
+ retVal = false;
+#if OSL_DEBUG_LEVEL > 1
+ else
+ OSL_ASSERT(0);
+#endif
+ }
+ else if (dwType == REG_DWORD)
+ {
+ if (arData[0] == 1)
+ retVal = true;
+ else if (arData[0] == 0)
+ retVal = false;
+#if OSL_DEBUG_LEVEL > 1
+ else
+ OSL_ASSERT(0);
+#endif
+ }
+ }
+ }
+ RegCloseKey(hKey);
+
+#elif UNX
+ char buf[16];
+ // use 2 shells to suppress the eventual "gcontool-2 not found" message
+ // of the shell trying to execute the command
+ FILE* fp = popen( "/bin/sh 2>/dev/null -c \"gconftool-2 -g /desktop/gnome/interface/accessibility\"", "r" );
+ if( fp )
+ {
+ if( fgets( buf, sizeof(buf), fp ) )
+ {
+ int nCompare = strncasecmp( buf, "true", 4 );
+ retVal = (nCompare == 0 ? true : false);
+ }
+ pclose( fp );
+ }
+#endif
+ return retVal;
+}
+
+
+rtl::ByteSequence encodeBase16(const rtl::ByteSequence& rawData)
+{
+ static char EncodingTable[] =
+ {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+ sal_Int32 lenRaw = rawData.getLength();
+ char* pBuf = new char[lenRaw * 2];
+ const sal_Int8* arRaw = rawData.getConstArray();
+
+ char* pCurBuf = pBuf;
+ for (int i = 0; i < lenRaw; i++)
+ {
+ unsigned char curChar = arRaw[i];
+ curChar >>= 4;
+
+ *pCurBuf = EncodingTable[curChar];
+ pCurBuf++;
+
+ curChar = arRaw[i];
+ curChar &= 0x0F;
+
+ *pCurBuf = EncodingTable[curChar];
+ pCurBuf++;
+ }
+
+ rtl::ByteSequence ret((sal_Int8*) pBuf, lenRaw * 2);
+ delete [] pBuf;
+ return ret;
+}
+
+rtl::ByteSequence decodeBase16(const rtl::ByteSequence& data)
+{
+ static char decodingTable[] =
+ {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+ sal_Int32 lenData = data.getLength();
+ sal_Int32 lenBuf = lenData / 2; //always divisable by two
+ unsigned char* pBuf = new unsigned char[lenBuf];
+ const sal_Int8* pData = data.getConstArray();
+ for (sal_Int32 i = 0; i < lenBuf; i++)
+ {
+ sal_Int8 curChar = *pData++;
+ //find the index of the first 4bits
+ // TODO What happens if text is not valid Hex characters?
+ unsigned char nibble = 0;
+ for (unsigned char j = 0; j < 16; j++)
+ {
+ if (curChar == decodingTable[j])
+ {
+ nibble = j;
+ break;
+ }
+ }
+ nibble <<= 4;
+ curChar = *pData++;
+ //find the index for the next 4bits
+ for (unsigned char j = 0; j < 16; j++)
+ {
+ if (curChar == decodingTable[j])
+ {
+ nibble |= j;
+ break;
+ }
+ }
+ pBuf[i] = nibble;
+ }
+ rtl::ByteSequence ret((sal_Int8*) pBuf, lenBuf );
+ delete [] pBuf;
+ return ret;
+}
+
+rtl::OUString getDirFromFile(const rtl::OUString& usFilePath)
+{
+ sal_Int32 index= usFilePath.lastIndexOf('/');
+ return rtl::OUString(usFilePath.getStr(), index);
+}
+
+rtl::OUString getExecutableDirectory()
+{
+ rtl_uString* sExe = NULL;
+ if (osl_getExecutableFile( & sExe) != osl_Process_E_None)
+ throw FrameworkException(
+ JFW_E_ERROR,
+ "[Java framework] Error in function getExecutableDirectory (fwkutil.cxx)");
+
+ rtl::OUString ouExe(sExe, SAL_NO_ACQUIRE);
+ return getDirFromFile(ouExe);
+}
+
+rtl::OUString findPlugin(
+ const rtl::OUString & baseUrl, const rtl::OUString & plugin)
+{
+ rtl::OUString expandedPlugin;
+ try
+ {
+ expandedPlugin = cppu::bootstrap_expandUri(plugin);
+ }
+ catch (com::sun::star::lang::IllegalArgumentException & e)
+ {
+ throw FrameworkException(
+ JFW_E_ERROR,
+ (rtl::OString(
+ RTL_CONSTASCII_STRINGPARAM(
+ "[Java framework] IllegalArgumentException in"
+ " findPlugin: "))
+ + rtl::OUStringToOString(e.Message, osl_getThreadTextEncoding())));
+ }
+ rtl::OUString sUrl;
+ try
+ {
+ sUrl = rtl::Uri::convertRelToAbs(baseUrl, expandedPlugin);
+ }
+ catch (rtl::MalformedUriException & e)
+ {
+ throw FrameworkException(
+ JFW_E_ERROR,
+ (rtl::OString(
+ RTL_CONSTASCII_STRINGPARAM(
+ "[Java framework] rtl::MalformedUriException in"
+ " findPlugin: "))
+ + rtl::OUStringToOString(
+ e.getMessage(), osl_getThreadTextEncoding())));
+ }
+ if (checkFileURL(sUrl) == jfw::FILE_OK)
+ {
+ return sUrl;
+ }
+ rtl::OUString retVal;
+ rtl::OUString sProgDir = getExecutableDirectory();
+ sUrl = sProgDir + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"))
+ + plugin;
+ jfw::FileStatus s = checkFileURL(sUrl);
+ if (s == jfw::FILE_INVALID || s == jfw::FILE_DOES_NOT_EXIST)
+ {
+ //If only the name of the library is given, then
+ //use PATH, LD_LIBRARY_PATH etc. to locate the plugin
+ if (plugin.indexOf('/') == -1)
+ {
+ rtl::OUString url;
+#ifdef UNX
+#if defined(MACOSX)
+ rtl::OUString path = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DYLD_LIBRARY_PATH"));
+#elif defined(AIX)
+ rtl::OUString path = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LIBPATH"));
+#else
+ rtl::OUString path = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LD_LIBRARY_PATH"));
+#endif
+ rtl::OUString env_path;
+ oslProcessError err = osl_getEnvironment(path.pData, &env_path.pData);
+ if (err != osl_Process_E_None && err != osl_Process_E_NotFound)
+ throw FrameworkException(
+ JFW_E_ERROR,
+ "[Java framework] Error in function findPlugin (fwkutil.cxx).");
+ if (err == osl_Process_E_NotFound)
+ return retVal;
+ if (osl_searchFileURL(plugin.pData, env_path.pData, &url.pData)
+ == osl_File_E_None)
+#else
+ if (osl_searchFileURL(plugin.pData, NULL, &url.pData)
+ == osl_File_E_None)
+#endif
+ retVal = url;
+ else
+ throw FrameworkException(
+ JFW_E_ERROR,
+ "[Java framework] Error in function findPlugin (fwkutil.cxx).");
+ }
+ }
+ else
+ {
+ retVal = sUrl;
+ }
+ return retVal;
+}
+
+rtl::OUString getLibraryLocation()
+{
+ rtl::OString sExcMsg("[Java framework] Error in function getLibraryLocation "
+ "(fwkutil.cxx).");
+ rtl::OUString libraryFileUrl;
+
+ if (!osl::Module::getUrlFromAddress(
+ reinterpret_cast< oslGenericFunction >(getLibraryLocation),
+ libraryFileUrl))
+ throw FrameworkException(JFW_E_ERROR, sExcMsg);
+
+ return getDirFromFile(libraryFileUrl);
+}
+
+jfw::FileStatus checkFileURL(const rtl::OUString & sURL)
+{
+ jfw::FileStatus ret = jfw::FILE_OK;
+ DirectoryItem item;
+ File::RC rc_item = DirectoryItem::get(sURL, item);
+ if (File::E_None == rc_item)
+ {
+ osl::FileStatus status(FileStatusMask_Validate);
+
+ File::RC rc_stat = item.getFileStatus(status);
+ if (File::E_None == rc_stat)
+ {
+ ret = FILE_OK;
+ }
+ else if (File::E_NOENT == rc_stat)
+ {
+ ret = FILE_DOES_NOT_EXIST;
+ }
+ else
+ {
+ ret = FILE_INVALID;
+ }
+ }
+ else if (File::E_NOENT == rc_item)
+ {
+ ret = FILE_DOES_NOT_EXIST;
+ }
+ else
+ {
+ ret = FILE_INVALID;
+ }
+ return ret;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/jvmfwk/source/fwkutil.hxx b/jvmfwk/source/fwkutil.hxx
new file mode 100644
index 000000000000..9e241cf92efe
--- /dev/null
+++ b/jvmfwk/source/fwkutil.hxx
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#if !defined INCLUDED_JVMFWK_FWKUTIL_HXX
+#define INCLUDED_JVMFWK_FWKUTIL_HXX
+
+#include "sal/config.h"
+#include "osl/mutex.hxx"
+#include "rtl/bootstrap.hxx"
+#include "rtl/instance.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/byteseq.hxx"
+#include "osl/thread.hxx"
+#if OSL_DEBUG_LEVEL >=2
+#include <stdio.h>
+#endif
+
+
+namespace jfw
+{
+
+/** Returns the file URL of the directory where the framework library
+ (this library) resides.
+*/
+rtl::OUString getLibraryLocation();
+
+/** provides a bootstrap class which already knows the values from the
+ jvmfkwrc file.
+*/
+struct Bootstrap :
+ public ::rtl::StaticWithInit< const rtl::Bootstrap *, Bootstrap > {
+ const rtl::Bootstrap * operator () () {
+ ::rtl::OUStringBuffer buf(256);
+ buf.append(getLibraryLocation());
+ buf.appendAscii(SAL_CONFIGFILE("/jvmfwk3"));
+ ::rtl::OUString sIni = buf.makeStringAndClear();
+ ::rtl::Bootstrap * bootstrap = new ::rtl::Bootstrap(sIni);
+#if OSL_DEBUG_LEVEL >=2
+ rtl::OString o = rtl::OUStringToOString( sIni , osl_getThreadTextEncoding() );
+ fprintf(stderr, "[Java framework] Using configuration file %s\n" , o.getStr() );
+#endif
+ return bootstrap;
+ }
+};
+
+struct FwkMutex: public ::rtl::Static<osl::Mutex, FwkMutex> {};
+
+rtl::ByteSequence encodeBase16(const rtl::ByteSequence& rawData);
+rtl::ByteSequence decodeBase16(const rtl::ByteSequence& data);
+
+rtl::OUString getPlatform();
+
+
+rtl::OUString getDirFromFile(const rtl::OUString& usFilePath);
+
+/** Returns the file URL of the folder where the executable resides.
+ */
+rtl::OUString getExecutableDirectory();
+/** Locates the plugin library and returns the file URL.
+
+ First tries to locate plugin relative to baseUrl (if relative);
+ vnd.sun.star.expand URLs are supported. If that fails, tries to
+ locate plugin relative to the executable. If that fails, and plugin
+ contains no slashes, tries to locate plugin in a platform-specific way
+ (e.g., LD_LIBRARY_PATH).
+
+ @param baseUrl
+ The base file URL relative to which the plugin argument is interpreted.
+
+ @param plugin
+ The argument is an absolute or relative URL or just the name of the plugin.
+ */
+rtl::OUString findPlugin(
+ const rtl::OUString & baseUrl, const rtl::OUString & plugin);
+
+
+enum FileStatus
+{
+ FILE_OK,
+ FILE_DOES_NOT_EXIST,
+ FILE_INVALID
+};
+
+/** checks if the URL is a file.
+
+ If it is a link to a file than
+ it is resolved. Assuming that the argument
+ represents a relative URL then FILE_INVALID
+ is returned.
+
+
+ @return
+ one of the values of FileStatus.
+
+ @exception
+ Errors occurred during determining if the file exists
+ */
+FileStatus checkFileURL(const rtl::OUString & path);
+
+
+struct PluginLibrary;
+class VersionInfo;
+class CJavaInfo;
+
+bool isAccessibilitySupportDesired();
+
+rtl::OUString buildClassPathFromDirectory(const rtl::OUString & relPath);
+
+rtl::OUString retrieveClassPath( ::rtl::OUString const & macro );
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/jvmfwk/source/javasettings.xsd b/jvmfwk/source/javasettings.xsd
new file mode 100644
index 000000000000..3b3b28f2192e
--- /dev/null
+++ b/jvmfwk/source/javasettings.xsd
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Document : javasettings.xsd
+ Created on : 25. März 2004, 16:16
+ Author : jl97489
+ Description:
+ Purpose of XML Schema document follows.
+-->
+
+<schema targetNamespace="http://openoffice.org/2004/java/framework/1.0"
+ xmlns:jf="http://openoffice.org/2004/java/framework/1.0"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified">
+
+<element name="java">
+ <complexType>
+ <sequence>
+ <element name="enabled" nillable="true" default="true" type="boolean"/>
+ <element name="userClassPath" nillable="true" type="string"/>
+ <element name="vmParameters" nillable="true" type="jf:vmParametersType"/>
+ <element name="jreLocations" nillable="true" type="jf:jreLocationsType"/>
+ <element name="javaInfo" nillable="true" type="jf:javaInfoType"/>
+ </sequence>
+ </complexType>
+
+</element>
+
+<complexType name="javaInfoType">
+ <sequence>
+ <element name="vendor" type="string"/>
+ <element name="location" type="string"/>
+ <element name="version" type="string"/>
+ <element name="features" default="0" type="unsignedLong"/>
+ <element name="requirements" default="0" type="unsignedLong"/>
+ <element name="vendorData" type="base64Binary"/>
+ </sequence>
+ <attribute name="vendorUpdate" type="date"/>
+</complexType>
+
+
+<complexType name="vmParametersType">
+ <sequence>
+ <element name="param" minOccurs="0" maxOccurs="unbounded" type="string"/>
+ </sequence>
+</complexType>
+
+<complexType name="jreLocationsType">
+ <sequence>
+ <element name="location" minOccurs="0" maxOccurs="unbounded" type="string"/>
+ </sequence>
+</complexType>
+
+</schema>
diff --git a/jvmfwk/source/javasettings_template.xml b/jvmfwk/source/javasettings_template.xml
new file mode 100644
index 000000000000..3512501d3ee4
--- /dev/null
+++ b/jvmfwk/source/javasettings_template.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+This file shows what elements the javasettings_platform.xml can contain.
+The children of javaInfo are only created when a JRE is selected. The children of
+vmParameters are only created when parameters are added and the children of
+jreLocations are only created when the paths are added.
+See CNodeJava::loadFromSettings and CNodeJava::writeSettings for details.
+When extending the javavendors.xml then use the schema to verify it.
+-->
+
+<java xmlns='http://openoffice.org/2004/java/framework/1.0'
+ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xsi:schemaLocation='http://openoffice.org/2004/java/framework/1.0 file:/D:/cws-jl6/jvmfwk/source/javasettings.xsd'>
+ <classesDirectory>program/classes</classesDirectory>
+ <enabled xsi:nil="true"></enabled>
+ <userClassPath xsi:nil="true"></userClassPath>
+ <vmParameters xsi:nil="true"/>
+ <!--param>-Xdebug</param-->
+ <!--</vmParameters>-->
+ <jreLocations xsi:nil="true"/>
+ <!--location></location-->
+ <!--</jreLocations>-->
+ <javaInfo xsi:nil="true"/>
+ <!--javaInfo vendorUpdate="2004-03-27" xsi:nil="false"-->
+ <!--vendor></vendor>
+ <location></location>
+ <version></version>
+ <features></features>
+ <requirements></requirements>
+ <vendorData></vendorData>
+ </javaInfo-->
+ </java>
+
+
diff --git a/jvmfwk/source/javasettingsunopkginstall.xml b/jvmfwk/source/javasettingsunopkginstall.xml
new file mode 100644
index 000000000000..3efc8e87fc62
--- /dev/null
+++ b/jvmfwk/source/javasettingsunopkginstall.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<java xmlns="http://openoffice.org/2004/java/framework/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+</java>
diff --git a/jvmfwk/source/jvmfwk3rc b/jvmfwk/source/jvmfwk3rc
new file mode 100644
index 000000000000..048b16e7ab3b
--- /dev/null
+++ b/jvmfwk/source/jvmfwk3rc
@@ -0,0 +1,4 @@
+[Bootstrap]
+UNO_JAVA_JFW_ENV_JREHOME=true
+UNO_JAVA_JFW_ENV_CLASSPATH=true
+UNO_JAVA_JFW_VENDOR_SETTINGS=javavendors.xml \ No newline at end of file
diff --git a/jvmfwk/source/libxmlutil.cxx b/jvmfwk/source/libxmlutil.cxx
new file mode 100644
index 000000000000..e121712d8672
--- /dev/null
+++ b/jvmfwk/source/libxmlutil.cxx
@@ -0,0 +1,187 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_jvmfwk.hxx"
+#include "libxmlutil.hxx"
+
+namespace jfw
+{
+
+CXPathObjectPtr::CXPathObjectPtr(xmlXPathObject* aObject)
+ : _object(aObject)
+{
+}
+
+CXPathObjectPtr::CXPathObjectPtr():_object(NULL)
+{
+}
+
+CXPathObjectPtr::~CXPathObjectPtr()
+{
+ xmlXPathFreeObject(_object);
+}
+CXPathObjectPtr & CXPathObjectPtr::operator = (xmlXPathObject* pObj)
+{
+ if (_object == pObj)
+ return *this;
+
+ xmlXPathFreeObject(_object);
+ _object = pObj;
+ return *this;
+}
+xmlXPathObject* CXPathObjectPtr::operator ->()
+
+{
+ return _object;
+}
+CXPathObjectPtr::operator xmlXPathObject*()
+{
+ return _object;
+}
+//===========================================================
+CXPathContextPtr::CXPathContextPtr(xmlXPathContextPtr aContext)
+ : _object(aContext)
+{
+}
+
+CXPathContextPtr::CXPathContextPtr():_object(NULL)
+{
+}
+
+CXPathContextPtr::~CXPathContextPtr()
+{
+ xmlXPathFreeContext(_object);
+}
+
+CXPathContextPtr & CXPathContextPtr::operator = (xmlXPathContextPtr pObj)
+{
+ if (_object == pObj)
+ return *this;
+ xmlXPathFreeContext(_object);
+ _object = pObj;
+ return *this;
+}
+xmlXPathContext* CXPathContextPtr::operator ->()
+{
+ return _object;
+}
+
+CXPathContextPtr::operator xmlXPathContext*()
+{
+ return _object;
+}
+//===========================================================
+CXmlDocPtr::CXmlDocPtr(xmlDoc* aDoc)
+ : _object(aDoc)
+{
+}
+
+CXmlDocPtr::CXmlDocPtr():_object(NULL)
+{
+}
+
+CXmlDocPtr::~CXmlDocPtr()
+{
+ xmlFreeDoc(_object);
+}
+CXmlDocPtr & CXmlDocPtr::operator = (xmlDoc* pObj)
+{
+ if (_object == pObj)
+ return *this;
+ xmlFreeDoc(_object);
+ _object = pObj;
+ return *this;
+}
+
+xmlDoc* CXmlDocPtr::operator ->()
+{
+ return _object;
+}
+
+CXmlDocPtr::operator xmlDoc*()
+{
+ return _object;
+}
+
+//===========================================================
+CXmlCharPtr::CXmlCharPtr(xmlChar * aChar)
+ : _object(aChar)
+{
+}
+
+CXmlCharPtr::CXmlCharPtr(const ::rtl::OUString & s):
+ _object(NULL)
+{
+ ::rtl::OString o = ::rtl::OUStringToOString(s, RTL_TEXTENCODING_UTF8);
+ _object = xmlCharStrdup(o.getStr());
+}
+CXmlCharPtr::CXmlCharPtr():_object(NULL)
+{
+}
+
+CXmlCharPtr::~CXmlCharPtr()
+{
+ xmlFree(_object);
+}
+
+CXmlCharPtr & CXmlCharPtr::operator = (xmlChar* pObj)
+{
+ if (pObj == _object)
+ return *this;
+ xmlFree(_object);
+ _object = pObj;
+ return *this;
+}
+
+CXmlCharPtr::operator xmlChar*()
+{
+ return _object;
+}
+
+CXmlCharPtr::operator ::rtl::OUString()
+{
+ ::rtl::OUString ret;
+ if (_object != NULL)
+ {
+ ::rtl::OString aOStr((sal_Char*)_object);
+ ret = ::rtl::OStringToOUString(aOStr, RTL_TEXTENCODING_UTF8);
+ }
+ return ret;
+}
+
+CXmlCharPtr::operator ::rtl::OString()
+{
+ return ::rtl::OString((sal_Char*) _object);
+}
+
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/jvmfwk/source/libxmlutil.hxx b/jvmfwk/source/libxmlutil.hxx
new file mode 100644
index 000000000000..b8c4a6e2f388
--- /dev/null
+++ b/jvmfwk/source/libxmlutil.hxx
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#if !defined INCLUDED_JVMFWK_LIBXMLUTIL_HXX
+#define INCLUDED_JVMFWK_LIBXMLUTIL_HXX
+
+
+#include "libxml/parser.h"
+#include "libxml/xpath.h"
+#include "rtl/ustring.hxx"
+namespace jfw
+{
+class CXPathObjectPtr
+{
+ xmlXPathObject* _object;
+ CXPathObjectPtr & operator = (const CXPathObjectPtr&);
+ CXPathObjectPtr(const CXPathObjectPtr&);
+public:
+ CXPathObjectPtr();
+ /** Takes ownership of xmlXPathObject
+ */
+ CXPathObjectPtr(xmlXPathObject* aObject);
+ ~CXPathObjectPtr();
+ /** Takes ownership of xmlXPathObject
+ */
+ CXPathObjectPtr & operator = (xmlXPathObject* pObj);
+ xmlXPathObject* operator -> ();
+ operator xmlXPathObject* ();
+};
+
+//===========================================================
+class CXPathContextPtr
+{
+ xmlXPathContext* _object;
+
+ CXPathContextPtr(const jfw::CXPathContextPtr&);
+ CXPathContextPtr & operator = (const CXPathContextPtr&);
+public:
+ CXPathContextPtr();
+ CXPathContextPtr(xmlXPathContextPtr aContext);
+ CXPathContextPtr & operator = (xmlXPathContextPtr pObj);
+ ~CXPathContextPtr();
+ xmlXPathContext* operator -> ();
+ operator xmlXPathContext* ();
+};
+
+//===========================================================
+class CXmlDocPtr
+{
+ xmlDoc* _object;
+
+ CXmlDocPtr(const CXmlDocPtr&);
+
+public:
+ CXmlDocPtr & operator = (const CXmlDocPtr&);
+ CXmlDocPtr();
+ CXmlDocPtr(xmlDoc* aDoc);
+ /** Takes ownership of xmlDoc
+ */
+ CXmlDocPtr & operator = (xmlDoc* pObj);
+ ~CXmlDocPtr();
+ xmlDoc* operator -> ();
+ operator xmlDoc* ();
+};
+
+//===========================================================
+class CXmlCharPtr
+{
+ xmlChar* _object;
+
+ CXmlCharPtr(const CXmlCharPtr&);
+ CXmlCharPtr & operator = (const CXmlCharPtr&);
+public:
+ CXmlCharPtr();
+ CXmlCharPtr(xmlChar* aDoc);
+ CXmlCharPtr(const ::rtl::OUString &);
+ ~CXmlCharPtr();
+ CXmlCharPtr & operator = (xmlChar* pObj);
+// xmlChar* operator -> ();
+ operator xmlChar* ();
+ operator ::rtl::OUString ();
+ operator ::rtl::OString ();
+};
+
+
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/jvmfwk/source/makefile.mk b/jvmfwk/source/makefile.mk
new file mode 100644
index 000000000000..d43a31bc642d
--- /dev/null
+++ b/jvmfwk/source/makefile.mk
@@ -0,0 +1,87 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..
+PRJNAME = jvmfwk
+FRAMEWORKLIB=jvmfwk
+TARGET = $(FRAMEWORKLIB)
+ENABLE_EXCEPTIONS = TRUE
+
+.IF "$(OS)" != "WNT" && "$(GUI)"!="OS2"
+UNIXVERSIONNAMES = UDK
+.ENDIF # WNT
+
+.INCLUDE: settings.mk
+
+.IF "$(SYSTEM_LIBXML)" == "YES"
+CFLAGS+=-DSYSTEM_LIBXML $(LIBXML_CFLAGS)
+.ENDIF
+
+UNOUCROUT = $(OUT)$/inc
+
+SLOFILES = \
+ $(SLO)$/framework.obj \
+ $(SLO)$/libxmlutil.obj \
+ $(SLO)$/fwkutil.obj \
+ $(SLO)$/elements.obj \
+ $(SLO)$/fwkbase.obj
+
+
+.IF "$(UNIXVERSIONNAMES)" == ""
+SHL1TARGET = $(FRAMEWORKLIB)$(UDK_MAJOR)
+.ELSE # UNIXVERSIONNAMES
+SHL1TARGET = $(FRAMEWORKLIB)
+.ENDIF # UNIXVERSIONNAMES
+
+SHL1DEPN=
+SHL1IMPLIB = i$(FRAMEWORKLIB)
+SHL1LIBS = $(SLB)$/$(TARGET).lib
+SHL1STDLIBS = $(CPPUHELPERLIB) $(SALLIB) $(LIBXML2LIB)
+SHL1RPATH = URELIB
+
+.IF "$(OS)" == "WNT"
+SHL1STDLIBS += $(ADVAPI32LIB)
+.ENDIF # WNT
+
+SHL1VERSIONMAP = framework.map
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME = $(SHL1TARGET)
+
+.IF "$(GUI)"=="UNX"
+RCFILE=$(BIN)$/jvmfwk3rc
+.ELIF "$(GUI)"=="WNT" || "$(GUI)"=="OS2"
+RCFILE=$(BIN)$/jvmfwk3.ini
+.END
+
+
+.INCLUDE: target.mk
+$(RCFILE): jvmfwk3rc
+ -$(COPY) $< $@
+
+ALLTAR: \
+ $(RCFILE)
+
diff --git a/jvmfwk/source/readme.txt b/jvmfwk/source/readme.txt
new file mode 100644
index 000000000000..f4e822513de5
--- /dev/null
+++ b/jvmfwk/source/readme.txt
@@ -0,0 +1,9 @@
+The file jvfwk3rc is intended for providing bootstrap parameter for the java
+framework within the build environment. It is not part of a product. Tools
+which are started in the environment, such as regcomp.exe and uno.exe, use
+this rc file when Java is needed.
+
+The file javasettingsunopkginstall.xml only contains the root element of
+a settings file (<java ...>). It is a dummy which will be installed into
+office/share/config/. Bundled extensions will used this file to store its
+java settings. See framework.h bootstrap variable UNO_JAVA_JFW_INSTALL_DATA