/**************************************************************
 *
 * 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
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the 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>
// #define NS_JAVA_FRAMEWORK "http://openoffice.org/2004/java/framework/1.0"
// #define NS_SCHEMA_INSTANCE "http://www.w3.org/2001/XMLSchema-instance"


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* pbNeedsSave)
{
    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)
	{
		*pbNeedsSave = false;
        return;
	}
    //We will modify this document
    *pbNeedsSave = 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"  autoSelect="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");
//    xmlSetProp(nodeJava,(xmlChar*) "autoSelect",(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_ASSERT("[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_ASSERT("[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_ASSERT("[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 every time
            //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 modTime = stat.getModifyTime();
                ::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(OpenFlag_Write | 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
{
    sal_uInt32 ret = 0;
    if (m_layer != INSTALL)
    {
        OSL_ASSERT(0);
        return ret;
    }
    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;
}
}
