/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
 
#include <sal/config.h>
#include <sal/log.hxx>
 
#include <cassert>
#include <memory>
#include <utility>
 
#include <rtl/ustring.hxx>
#include <rtl/bootstrap.hxx>
#include <osl/thread.hxx>
#include <osl/file.hxx>
#include <jvmfwk/framework.hxx>
#include <vendorplugin.hxx>
#include <vector>
#include <algorithm>
#include "framework.hxx"
#include <fwkutil.hxx>
#include <elements.hxx>
#include "fwkbase.hxx"
 
namespace {
 
static bool g_bEnabledSwitchedOn = false;
 
static JavaVM * g_pJavaVM = nullptr;
 
bool areEqualJavaInfo(
    JavaInfo const * pInfoA,JavaInfo const * pInfoB)
{
    return jfw_areEqualJavaInfo(pInfoA, pInfoB);
}
 
}
 
javaFrameworkError jfw_findAllJREs(std::vector<std::unique_ptr<JavaInfo>> *pparInfo)
{
    assert(pparInfo != nullptr);
    try
    {
        osl::MutexGuard guard(jfw::FwkMutex::get());
 
        jfw::VendorSettings aVendorSettings;
        std::vector<OUString> vecVendors =
            aVendorSettings.getSupportedVendors();
        //Add the JavaInfos found by jfw_plugin_getAllJavaInfos to the vector
        std::vector<std::unique_ptr<JavaInfo>> vecInfo;
        //get the list of paths to jre locations which have been
        //added manually
        const jfw::MergedSettings settings;
        const std::vector<OUString>& vecJRELocations =
            settings.getJRELocations();
        //Use every plug-in library to get Java installations.
        for (auto const & vendor: vecVendors)
        {
            jfw::VersionInfo versionInfo =
                aVendorSettings.getVersionInformation(vendor);
 
            //get all installations of one vendor according to minVersion,
            //maxVersion and excludeVersions
            std::vector<std::unique_ptr<JavaInfo>> arInfos;
            std::vector<rtl::Reference<jfw_plugin::VendorBase>> infos;
            javaPluginError plerr = jfw_plugin_getAllJavaInfos(
                true,
                vendor,
                versionInfo.sMinVersion,
                versionInfo.sMaxVersion,
                versionInfo.vecExcludeVersions,
                & arInfos,
                infos);
 
            if (plerr != javaPluginError::NONE)
                return JFW_E_ERROR;
 
            for (auto & j: arInfos)
                vecInfo.push_back(std::move(j));
 
            //Check if the current plugin can detect JREs at the location
            // of the paths added by jfw_addJRELocation
            //Check every manually added location
            for (auto const & ii: vecJRELocations)
            {
                std::unique_ptr<JavaInfo> aInfo;
                plerr = jfw_plugin_getJavaInfoByPath(
                    ii,
                    vendor,
                    versionInfo.sMinVersion,
                    versionInfo.sMaxVersion,
                    versionInfo.vecExcludeVersions,
                    &aInfo);
                if (plerr == javaPluginError::NoJre)
                    continue;
                if (plerr == javaPluginError::FailedVersion)
                    continue;
                else if (plerr != javaPluginError::NONE)
                    return JFW_E_ERROR;
 
                // Was this JRE already added?  Different plugins could detect
                // the same JRE.  Also make sure vecInfo contains only JavaInfos
                // for the vendors for which there is a javaSelection/plugins/
                // library entry in the javavendors.xml; jfw_getJavaInfoByPath
                // can return a JavaInfo of any vendor:
                if ((std::none_of(
                         vecInfo.begin(), vecInfo.end(),
                         [&aInfo](std::unique_ptr<JavaInfo> const & info) {
                             return areEqualJavaInfo(
                                 info.get(), aInfo.get());
                         }))
                    && (std::find(
                            vecVendors.begin(), vecVendors.end(),
                            aInfo->sVendor)
                        != vecVendors.end()))
                {
                    vecInfo.push_back(std::move(aInfo));
                }
            }
        }
 
        *pparInfo = std::move(vecInfo);
 
        return JFW_E_NONE;
    }
    catch (const jfw::FrameworkException& e)
    {
        SAL_WARN( "jfw", e.message);
        return e.errorCode;
    }
}
 
javaFrameworkError jfw_startVM(
    JavaInfo const * pInfo, std::vector<OUString> const & arOptions,
    JavaVM ** ppVM, JNIEnv ** ppEnv)
{
    assert(ppVM != nullptr);
    javaFrameworkError errcode = JFW_E_NONE;
 
    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 != nullptr)
            return JFW_E_RUNNING_JVM;
 
        std::vector<OString> vmParams;
        OString sUserClassPath;
        std::unique_ptr<JavaInfo> aInfo;
        if (pInfo == nullptr)
        {
            jfw::JFW_MODE mode = jfw::getMode();
            if (mode == jfw::JFW_MODE_APPLICATION)
            {
                const jfw::MergedSettings settings;
                if (!settings.getEnabled())
                    return JFW_E_JAVA_DISABLED;
                aInfo = settings.createJavaInfo();
                //check if a Java has ever been selected
                if (!aInfo)
                    return JFW_E_NO_SELECT;
 
#ifdef _WIN32
                //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 &&
                        (aInfo->nFeatures & JFW_FEATURE_ACCESSBRIDGE) == 0)
                    {
                        //has the user manually selected a JRE?
                        if (settings.getJavaInfoAttrAutoSelect())
                        {
                            // 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
                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 requirements flag JFW_REQUIRE_NEEDRESTART
                if ((aInfo->nRequirements & JFW_REQUIRE_NEEDRESTART)
                    && jfw::wasJavaSelectedInSameProcess())
                    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);
                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(false);
            pInfo = aInfo.get();
        }
        assert(pInfo != nullptr);
 
        // create JavaVMOptions array that is passed to the plugin
        // it contains the classpath and all options set in the
        //options dialog
        std::unique_ptr<JavaVMOption[]> sarJOptions(
            new JavaVMOption[
                arOptions.size() + (sUserClassPath.isEmpty() ? 1 : 2) + vmParams.size()]);
        JavaVMOption * arOpt = sarJOptions.get();
        if (! arOpt)
            return JFW_E_ERROR;
 
        //The first argument is the classpath
        int index = 0;
        if (!sUserClassPath.isEmpty()) {
            arOpt[index].optionString= const_cast<char*>(sUserClassPath.getStr());
            arOpt[index].extraInfo = nullptr;
            ++index;
        }
        // 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[index].optionString = const_cast<char *>("-Dorg.openoffice.native=");
        arOpt[index].extraInfo = nullptr;
        ++index;
 
        //add the options set by options dialog
        for (auto const & vmParam : vmParams)
        {
            arOpt[index].optionString = const_cast<sal_Char*>(vmParam.getStr());
            arOpt[index].extraInfo = nullptr;
            index ++;
        }
        //add all options of the arOptions argument
        std::vector<OString> convertedOptions;
        for (auto const & ii: arOptions)
        {
            OString conv = OUStringToOString(ii, osl_getThreadTextEncoding());
            convertedOptions.push_back(conv);
                // keep conv.getStr() alive until after the call to
                // jfw_plugin_startJavaVirtualMachine below
            arOpt[index].optionString = const_cast<char *>(conv.getStr());
            arOpt[index].extraInfo = nullptr;
            index++;
        }
 
        //start Java
        JavaVM *pVm = nullptr;
        SAL_INFO("jfw", "Starting Java");
        javaPluginError plerr = jfw_plugin_startJavaVirtualMachine(pInfo, arOpt, index, & pVm, ppEnv);
        if (plerr == javaPluginError::VmCreationFailed)
        {
            errcode = JFW_E_VM_CREATION_FAILED;
        }
        else if (plerr != javaPluginError::NONE )
        {
            errcode = JFW_E_ERROR;
        }
        else
        {
            g_pJavaVM = pVm;
            *ppVM = pVm;
        }
        OSL_ASSERT(plerr != javaPluginError::WrongVendor);
    }
    catch (const jfw::FrameworkException& e)
    {
        errcode = e.errorCode;
        SAL_WARN( "jfw", e.message);
    }
 
    return errcode;
}
 
/** 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 first inspects JAVA_HOME and
    PATH environment variables. If no suitable JavaInfo is found there, it
    inspects all JavaInfos found by the jfw_plugin_get* functions.
 */
javaFrameworkError jfw_findAndSelectJRE(std::unique_ptr<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;
        std::unique_ptr<JavaInfo> aCurrentInfo;
        //Determine if accessibility support is needed
        bool bSupportAccessibility = jfw::isAccessibilitySupportDesired();
        nFeatureFlags = bSupportAccessibility ?
            JFW_FEATURE_ACCESSBRIDGE : 0L;
 
 
        // 'bInfoFound' indicates whether a Java installation has been found
        // that supports all desired features
        bool bInfoFound = false;
 
        // get list of vendors for Java installations
        jfw::VendorSettings aVendorSettings;
        std::vector<OUString> vecVendors =
            aVendorSettings.getSupportedVendors();
 
        // save vendors and respective version requirements pair-wise in a vector
        std::vector<std::pair<OUString, jfw::VersionInfo>> versionInfos;
        for (auto const & vendor : vecVendors)
        {
            jfw::VersionInfo versionInfo =
                aVendorSettings.getVersionInformation(vendor);
 
            versionInfos.emplace_back(vendor, versionInfo);
        }
 
        std::vector<rtl::Reference<jfw_plugin::VendorBase>> infos;
 
        // first inspect Java installation that the JAVA_HOME
        // environment variable points to (if it is set)
        if (jfw_plugin_getJavaInfoFromJavaHome(
                versionInfos, &aCurrentInfo, infos)
            == javaPluginError::NONE)
        {
            // compare features
            // if the user does not require any features (nFeatureFlags = 0)
            // or the Java installation provides all features, then this installation is used
            if ((aCurrentInfo->nFeatures & nFeatureFlags) == nFeatureFlags)
            {
                bInfoFound = true;
            }
        }
 
        // if no Java installation providing all features was detected by using JAVA_HOME,
        // query PATH for Java installations
        if (!bInfoFound)
        {
            std::vector<std::unique_ptr<JavaInfo>> vecJavaInfosFromPath;
            if (jfw_plugin_getJavaInfosFromPath(
                    versionInfos, vecJavaInfosFromPath, infos)
                == javaPluginError::NONE)
            {
                for (auto & pJInfo: vecJavaInfosFromPath)
                {
                    // if the current Java installation implements all required features: use it
                    if ((pJInfo->nFeatures & nFeatureFlags) == nFeatureFlags)
                    {
                        aCurrentInfo = std::move(pJInfo);
                        bInfoFound = true;
                        break;
                    }
                    else if (!aCurrentInfo)
                    {
                        // current Java installation does not provide all features
                        // but no Java installation has been detected before
                        // -> remember the current one until one is found
                        // that provides all features
                        aCurrentInfo = std::move(pJInfo);
                    }
                }
            }
        }
 
 
        // if no suitable Java installation has been found yet:
        // first iterate over all vendors to find a suitable Java installation,
        // then try paths that have been added manually
        if (!bInfoFound)
        {
            //Use every vendor to get Java installations. At the first usable
            //Java the loop will break
            for (auto const & vendor : vecVendors)
            {
                jfw::VersionInfo versionInfo =
                    aVendorSettings.getVersionInformation(vendor);
 
                //get all installations of one vendor according to minVersion,
                //maxVersion and excludeVersions
                std::vector<std::unique_ptr<JavaInfo>> arInfos;
                javaPluginError plerr = jfw_plugin_getAllJavaInfos(
                    false,
                    vendor,
                    versionInfo.sMinVersion,
                    versionInfo.sMaxVersion,
                    versionInfo.vecExcludeVersions,
                    & arInfos,
                    infos);
 
                if (plerr != javaPluginError::NONE)
                    continue;
                //iterate over all installations to find the best which has
                //all features
                for (auto & pJInfo: arInfos)
                {
                    // 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 = std::move(pJInfo);
                        bInfoFound = true;
                        break;
                    }
                    else if (!aCurrentInfo)
                    {
                        // We remember the first installation in aCurrentInfo if
                        // no JavaInfo has been found before:
                        aCurrentInfo = std::move(pJInfo);
                    }
                }
 
                if (bInfoFound)
                    break;
                //All Java installations found by the current plug-in lib
                //do not provide the required features. Try the next plug-in
            }
            if (!aCurrentInfo)
            {//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<OUString> & vecJRELocations =
                    settings.getJRELocations();
                //use every plug-in to determine the JavaInfo objects
                for (auto const & vendor : vecVendors)
                {
                    jfw::VersionInfo versionInfo =
                        aVendorSettings.getVersionInformation(vendor);
 
                    for (auto const & JRELocation : vecJRELocations)
                    {
                        std::unique_ptr<JavaInfo> aInfo;
                        javaPluginError err = jfw_plugin_getJavaInfoByPath(
                            JRELocation,
                            vendor,
                            versionInfo.sMinVersion,
                            versionInfo.sMaxVersion,
                            versionInfo.vecExcludeVersions,
                            &aInfo);
                        if (err == javaPluginError::NoJre)
                            continue;
                        if (err == javaPluginError::FailedVersion)
                            continue;
                        else if (err !=javaPluginError::NONE)
                            return JFW_E_ERROR;
 
                        if (aInfo)
                        {
                            // compare features
                            // If the user does not require any features (nFeatureFlags = 0)
                            // then the first installation is used
                            if ((aInfo->nFeatures & nFeatureFlags) == nFeatureFlags)
                            {
                                //the just found Java implements all required features
                                //currently there is only accessibility!!!
                                aCurrentInfo = std::move(aInfo);
                                bInfoFound = true;
                                break;
                            }
                            else if (!aCurrentInfo)
                            {
                                // We remember the very first installation in
                                // aCurrentInfo:
                                aCurrentInfo = std::move(aInfo);
                            }
                        }
                    }//end iterate over paths
                    if (bInfoFound)
                        break;
                }// end iterate plug-ins
            }
        }
        if (aCurrentInfo)
        {
            jfw::NodeJava javaNode(jfw::NodeJava::USER);
            javaNode.setJavaInfo(aCurrentInfo.get(),true);
            javaNode.write();
            //remember that this JRE was selected in this process
            jfw::setJavaSelected();
 
            if (pInfo !=nullptr)
            {
                *pInfo = std::move(aCurrentInfo);
            }
        }
        else
        {
            errcode = JFW_E_NO_JAVA_FOUND;
        }
    }
    catch (const jfw::FrameworkException& e)
    {
        errcode = e.errorCode;
        SAL_WARN( "jfw", e.message );
    }
 
    return errcode;
}
 
bool jfw_areEqualJavaInfo(JavaInfo const * pInfoA,JavaInfo const * pInfoB)
{
    if (pInfoA == pInfoB)
        return true;
    if (pInfoA == nullptr || pInfoB == nullptr)
        return false;
    if (pInfoA->sVendor == pInfoB->sVendor
        && pInfoA->sLocation == pInfoB->sLocation
        && pInfoA->sVersion == pInfoB->sVersion
        && pInfoA->nFeatures == pInfoB->nFeatures
        && pInfoA->nRequirements == pInfoB->nRequirements
        && pInfoA->arVendorData == pInfoB->arVendorData)
    {
        return true;
    }
    return false;
}
 
javaFrameworkError jfw_getSelectedJRE(std::unique_ptr<JavaInfo> *ppInfo)
{
    assert(ppInfo != nullptr);
    javaFrameworkError errcode = JFW_E_NONE;
    try
    {
        osl::MutexGuard guard(jfw::FwkMutex::get());
 
        if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
        {
            if ((errcode = jfw_getJavaInfoByPath(
                     jfw::BootParams::getJREHome(), ppInfo))
                != JFW_E_NONE)
                throw jfw::FrameworkException(
                    JFW_E_CONFIGURATION,
                    "[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.");
 
            return JFW_E_NONE;
        }
 
        const jfw::MergedSettings settings;
        *ppInfo = settings.createJavaInfo();
        if (!*ppInfo)
        {
            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)
        OString sUpdated = jfw::getElementUpdated();
 
        if (sUpdated != settings.getJavaInfoAttrVendorUpdate())
        {
            ppInfo->reset();
            return JFW_E_INVALID_SETTINGS;
        }
    }
    catch (const jfw::FrameworkException& e)
    {
        errcode = e.errorCode;
        SAL_WARN( "jfw", e.message );
    }
    return errcode;
}
 
bool jfw_isVMRunning()
{
    osl::MutexGuard guard(jfw::FwkMutex::get());
    return g_pJavaVM != nullptr;
}
 
javaFrameworkError jfw_getJavaInfoByPath(OUString const & pPath, std::unique_ptr<JavaInfo> *ppInfo)
{
    assert(ppInfo != nullptr);
    javaFrameworkError errcode = JFW_E_NONE;
    try
    {
        osl::MutexGuard guard(jfw::FwkMutex::get());
 
        jfw::VendorSettings aVendorSettings;
        std::vector<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
        for (auto const & vendor : vecVendors)
        {
            jfw::VersionInfo versionInfo =
                aVendorSettings.getVersionInformation(vendor);
 
            //ask the plugin if this is a JRE.
            //If so check if it meets the version requirements.
            //Only if it does return a JavaInfo
            javaPluginError plerr = jfw_plugin_getJavaInfoByPath(
                pPath,
                vendor,
                versionInfo.sMinVersion,
                versionInfo.sMaxVersion,
                versionInfo.vecExcludeVersions,
                ppInfo);
 
            if (plerr == javaPluginError::NONE)
            {
                break;
            }
            else if(plerr == javaPluginError::FailedVersion)
            {//found JRE but it has the wrong version
                ppInfo->reset();
                errcode = JFW_E_FAILED_VERSION;
                break;
            }
            else if (plerr == javaPluginError::NoJre)
            {// plugin does not recognize this path as belonging to JRE
                continue;
            }
            OSL_ASSERT(false);
        }
        if (!*ppInfo && errcode != JFW_E_FAILED_VERSION)
            errcode = JFW_E_NOT_RECOGNIZED;
    }
    catch (const jfw::FrameworkException& e)
    {
        errcode = e.errorCode;
        SAL_WARN( "jfw", e.message );
    }
 
    return errcode;
}
 
 
javaFrameworkError 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
        std::unique_ptr<JavaInfo> currentInfo;
        errcode = jfw_getSelectedJRE( & currentInfo);
        if (errcode != JFW_E_NONE && errcode != JFW_E_INVALID_SETTINGS)
            return errcode;
 
        if (!jfw_areEqualJavaInfo(currentInfo.get(), pInfo))
        {
            jfw::NodeJava node(jfw::NodeJava::USER);
            node.setJavaInfo(pInfo, false);
            node.write();
            //remember that the JRE was selected in this process
            jfw::setJavaSelected();
        }
    }
    catch (const jfw::FrameworkException& e)
    {
        errcode = e.errorCode;
        SAL_WARN( "jfw", e.message );
    }
    return errcode;
}
javaFrameworkError jfw_setEnabled(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 && bEnabled)
        {
            //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())
                g_bEnabledSwitchedOn = true;
        }
        jfw::NodeJava node(jfw::NodeJava::USER);
        node.setEnabled(bEnabled);
        node.write();
    }
    catch (const jfw::FrameworkException& e)
    {
        errcode = e.errorCode;
        SAL_WARN( "jfw", e.message );
    }
    return errcode;
}
 
javaFrameworkError jfw_getEnabled(bool *pbEnabled)
{
    assert(pbEnabled != nullptr);
    javaFrameworkError errcode = JFW_E_NONE;
    try
    {
        if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
            return JFW_E_DIRECT_MODE;
        osl::MutexGuard guard(jfw::FwkMutex::get());
        jfw::MergedSettings settings;
        *pbEnabled = settings.getEnabled();
    }
    catch (const jfw::FrameworkException& e)
    {
        errcode = e.errorCode;
        SAL_WARN( "jfw", e.message );
    }
    return errcode;
}
 
 
javaFrameworkError jfw_setVMParameters(std::vector<OUString> const & arOptions)
{
    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(jfw::NodeJava::USER);
        node.setVmParameters(arOptions);
        node.write();
    }
    catch (const jfw::FrameworkException& e)
    {
        errcode = e.errorCode;
        SAL_WARN( "jfw", e.message );
    }
 
    return errcode;
}
 
javaFrameworkError jfw_getVMParameters(std::vector<OUString> * parOptions)
{
    javaFrameworkError errcode = JFW_E_NONE;
    try
    {
        osl::MutexGuard guard(jfw::FwkMutex::get());
        if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
            return JFW_E_DIRECT_MODE;
 
        const jfw::MergedSettings settings;
        settings.getVmParametersArray(parOptions);
    }
    catch (const jfw::FrameworkException& e)
    {
        errcode = e.errorCode;
        SAL_WARN( "jfw", e.message );
    }
    return errcode;
}
 
javaFrameworkError jfw_setUserClassPath(OUString const & 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(jfw::NodeJava::USER);
        node.setUserClassPath(pCp);
        node.write();
    }
    catch (const jfw::FrameworkException& e)
    {
        errcode = e.errorCode;
        SAL_WARN( "jfw", e.message );
    }
    return errcode;
}
 
javaFrameworkError jfw_getUserClassPath(OUString * ppCP)
{
    assert(ppCP != nullptr);
    javaFrameworkError errcode = JFW_E_NONE;
    try
    {
        osl::MutexGuard guard(jfw::FwkMutex::get());
        if (jfw::getMode() == jfw::JFW_MODE_DIRECT)
            return JFW_E_DIRECT_MODE;
        const jfw::MergedSettings settings;
        *ppCP = settings.getUserClassPath();
    }
    catch (const jfw::FrameworkException& e)
    {
        errcode = e.errorCode;
        SAL_WARN( "jfw", e.message );
    }
    return errcode;
}
 
javaFrameworkError jfw_addJRELocation(OUString const & 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(jfw::NodeJava::USER);
        node.load();
        node.addJRELocation(sLocation);
        node.write();
    }
    catch (const jfw::FrameworkException& e)
    {
        errcode = e.errorCode;
        SAL_WARN( "jfw", e.message );
    }
 
    return errcode;
 
}
 
javaFrameworkError jfw_existJRE(const JavaInfo *pInfo, bool *exist)
{
    javaPluginError plerr = jfw_plugin_existJRE(pInfo, exist);
 
    javaFrameworkError ret = JFW_E_NONE;
    switch (plerr)
    {
    case javaPluginError::NONE:
        ret = JFW_E_NONE;
        break;
    case javaPluginError::Error:
        ret = JFW_E_ERROR;
        break;
    default:
        ret = JFW_E_ERROR;
    }
    return ret;
}
 
void jfw_lock()
{
    jfw::FwkMutex::get().acquire();
}
 
void jfw_unlock()
{
    jfw::FwkMutex::get().release();
}
 
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

V547 Expression 'mode == jfw::JFW_MODE_DIRECT' is always true.

V547 Expression '!arOpt' is always false.