/**************************************************************
 *
 * 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_framework.hxx"

#include "services/modulemanager.hxx"
#include "services/frame.hxx"

//_______________________________________________
// own includes
#include <threadhelp/readguard.hxx>
#include <threadhelp/writeguard.hxx>
#include <services.h>

//_______________________________________________
// interface includes
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XModule.hpp>
#include <comphelper/configurationhelper.hxx>
#include <comphelper/sequenceashashmap.hxx>
#include <comphelper/sequenceasvector.hxx>
#include <comphelper/enumhelper.hxx>

//_______________________________________________
// other includes
#include <rtl/logfile.hxx>

namespace framework
{

static const ::rtl::OUString CFGPATH_FACTORIES     = ::rtl::OUString::createFromAscii("/org.openoffice.Setup/Office/Factories");
static const ::rtl::OUString MODULEPROP_IDENTIFIER = ::rtl::OUString::createFromAscii("ooSetupFactoryModuleIdentifier" );

/*-----------------------------------------------
    04.12.2003 09:32
-----------------------------------------------*/
DEFINE_XINTERFACE_7(ModuleManager                                    ,
                    OWeakObject                                      ,
                    DIRECT_INTERFACE(css::lang::XTypeProvider       ),
                    DIRECT_INTERFACE(css::lang::XServiceInfo        ),
                    DIRECT_INTERFACE(css::container::XNameReplace   ),
                    DIRECT_INTERFACE(css::container::XNameAccess    ),
                    DIRECT_INTERFACE(css::container::XElementAccess ),
                    DIRECT_INTERFACE(css::container::XContainerQuery),
                    DIRECT_INTERFACE(css::frame::XModuleManager     ))

/*-----------------------------------------------
    04.12.2003 09:32
-----------------------------------------------*/
DEFINE_XTYPEPROVIDER_7(ModuleManager                  ,
                       css::lang::XTypeProvider       ,
                       css::lang::XServiceInfo        ,
                       css::container::XNameReplace   ,
                       css::container::XNameAccess    ,
                       css::container::XElementAccess ,
                       css::container::XContainerQuery,
                       css::frame::XModuleManager     )

/*-----------------------------------------------
    04.12.2003 09:35
-----------------------------------------------*/
DEFINE_XSERVICEINFO_ONEINSTANCESERVICE(ModuleManager                   ,
                                       ::cppu::OWeakObject             ,
                                       SERVICENAME_MODULEMANAGER       ,
                                       IMPLEMENTATIONNAME_MODULEMANAGER)

/*-----------------------------------------------
    04.12.2003 09:35
-----------------------------------------------*/
DEFINE_INIT_SERVICE(
                    ModuleManager,
                    {
                        /*Attention
                            I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
                            to create a new instance of this class by our own supported service factory.
                            see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
                        */
                    }
                   )

/*-----------------------------------------------
    04.12.2003 09:30
-----------------------------------------------*/
ModuleManager::ModuleManager(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
    : ThreadHelpBase(     )
    , m_xSMGR       (xSMGR)
{
}

/*-----------------------------------------------
    10.12.2003 11:59
-----------------------------------------------*/
ModuleManager::~ModuleManager()
{
    if (m_xCFG.is())
        m_xCFG.clear();
}

/*-----------------------------------------------
    10.12.2003 11:02
-----------------------------------------------*/
::rtl::OUString SAL_CALL ModuleManager::identify(const css::uno::Reference< css::uno::XInterface >& xModule)
    throw(css::lang::IllegalArgumentException,
          css::frame::UnknownModuleException,
          css::uno::RuntimeException         )
{
    // valid parameter?
    css::uno::Reference< css::frame::XFrame >      xFrame     (xModule, css::uno::UNO_QUERY);
    css::uno::Reference< css::awt::XWindow >       xWindow    (xModule, css::uno::UNO_QUERY);
    css::uno::Reference< css::frame::XController > xController(xModule, css::uno::UNO_QUERY);
    css::uno::Reference< css::frame::XModel >      xModel     (xModule, css::uno::UNO_QUERY);

    if (
        (!xFrame.is()     ) &&
        (!xWindow.is()    ) &&
        (!xController.is()) &&
        (!xModel.is()     )
       )
    {
        throw css::lang::IllegalArgumentException(
                ::rtl::OUString::createFromAscii("Given module is not a frame nor a window, controller or model."),
                static_cast< ::cppu::OWeakObject* >(this),
                1);
    }

	if (xFrame.is())
    {
		xController = xFrame->getController();
        xWindow     = xFrame->getComponentWindow();
    }
    if (xController.is())
        xModel = xController->getModel();

    // modules are implemented by the deepest component in hierarchy ...
    // Means: model -> controller -> window
    // No fallbacks to higher components are allowed !
    // Note : A frame provides access to module components only ... but it's not a module by himself.

    ::rtl::OUString sModule;
    if (xModel.is())
        sModule = implts_identify(xModel);
    else
    if (xController.is())
        sModule = implts_identify(xController);
    else
    if (xWindow.is())
        sModule = implts_identify(xWindow);

    if (sModule.getLength() < 1)
        throw css::frame::UnknownModuleException(
                ::rtl::OUString::createFromAscii("Can't find suitable module for the given component."),
                static_cast< ::cppu::OWeakObject* >(this));

    return sModule;
}

/*-----------------------------------------------
    08.03.2007 09:55
-----------------------------------------------*/
void SAL_CALL ModuleManager::replaceByName(const ::rtl::OUString& sName ,
                                           const css::uno::Any&   aValue)
    throw (css::lang::IllegalArgumentException   ,
           css::container::NoSuchElementException,
           css::lang::WrappedTargetException     ,
           css::uno::RuntimeException            )
{
    ::comphelper::SequenceAsHashMap lProps(aValue);
    if (lProps.empty() )
    {
        throw css::lang::IllegalArgumentException(
                ::rtl::OUString::createFromAscii("No properties given to replace part of module."),
                static_cast< css::container::XNameAccess* >(this),
                2);
    }

    // SAFE -> ----------------------------------
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
    aReadLock.unlock();
    // <- SAFE ----------------------------------

    // get access to the element
    // Note: Dont use impl_getConfig() method here. Because it creates a readonly access only, further
    // it cache it as a member of this module manager instance. If we change some props there ... but dont
    // flush changes (because an error occurred) we will read them later. If we use a different config access
    // we can close it without a flush ... and our read data won't be affected .-)
    css::uno::Reference< css::uno::XInterface >         xCfg      = ::comphelper::ConfigurationHelper::openConfig(
                                                                        xSMGR,
                                                                        CFGPATH_FACTORIES,
                                                                        ::comphelper::ConfigurationHelper::E_STANDARD);
    css::uno::Reference< css::container::XNameAccess >  xModules (xCfg, css::uno::UNO_QUERY_THROW);
    css::uno::Reference< css::container::XNameReplace > xModule  ;

    xModules->getByName(sName) >>= xModule;
    if (!xModule.is())
    {
        throw css::uno::RuntimeException(
                ::rtl::OUString::createFromAscii("Was not able to get write access to the requested module entry inside configuration."),
                static_cast< css::container::XNameAccess* >(this));
    }

    ::comphelper::SequenceAsHashMap::const_iterator pProp;
    for (  pProp  = lProps.begin();
           pProp != lProps.end()  ;
         ++pProp                  )
    {
        const ::rtl::OUString& sPropName  = pProp->first;
        const css::uno::Any&   aPropValue = pProp->second;

        // let "NoSuchElementException" out ! We support the same API ...
        // and without a flush() at the end all changed data before will be ignored !
        xModule->replaceByName(sPropName, aPropValue);
    }

    ::comphelper::ConfigurationHelper::flush(xCfg);
}

/*-----------------------------------------------
    10.12.2003 12:05
-----------------------------------------------*/
css::uno::Any SAL_CALL ModuleManager::getByName(const ::rtl::OUString& sName)
    throw(css::container::NoSuchElementException,
          css::lang::WrappedTargetException     ,
          css::uno::RuntimeException            )
{
    // get access to the element
    css::uno::Reference< css::container::XNameAccess > xCFG = implts_getConfig();
    css::uno::Reference< css::container::XNameAccess > xModule;
    xCFG->getByName(sName) >>= xModule;
    if (!xModule.is())
    {
        throw css::uno::RuntimeException(
                ::rtl::OUString::createFromAscii("Was not able to get write access to the requested module entry inside configuration."),
                static_cast< css::container::XNameAccess* >(this));
    }

    // convert it to seq< PropertyValue >
    const css::uno::Sequence< ::rtl::OUString > lPropNames = xModule->getElementNames();
          ::comphelper::SequenceAsHashMap       lProps     ;
          sal_Int32                             c          = lPropNames.getLength();
          sal_Int32                             i          = 0;

    lProps[MODULEPROP_IDENTIFIER] <<= sName;
    for (i=0; i<c; ++i)
    {
        const ::rtl::OUString& sPropName         = lPropNames[i];
                               lProps[sPropName] = xModule->getByName(sPropName);
    }

    return css::uno::makeAny(lProps.getAsConstPropertyValueList());
}

/*-----------------------------------------------
    10.12.2003 11:58
-----------------------------------------------*/
css::uno::Sequence< ::rtl::OUString > SAL_CALL ModuleManager::getElementNames()
    throw(css::uno::RuntimeException)
{
    css::uno::Reference< css::container::XNameAccess > xCFG = implts_getConfig();
    return xCFG->getElementNames();
}

/*-----------------------------------------------
    10.12.2003 11:57
-----------------------------------------------*/
sal_Bool SAL_CALL ModuleManager::hasByName(const ::rtl::OUString& sName)
    throw(css::uno::RuntimeException)
{
    css::uno::Reference< css::container::XNameAccess > xCFG = implts_getConfig();
    return xCFG->hasByName(sName);
}

/*-----------------------------------------------
    10.12.2003 11:35
-----------------------------------------------*/
css::uno::Type SAL_CALL ModuleManager::getElementType()
    throw(css::uno::RuntimeException)
{
    return ::getCppuType((const css::uno::Sequence< css::beans::PropertyValue >*)0);
}

/*-----------------------------------------------
    10.12.2003 11:56
-----------------------------------------------*/
sal_Bool SAL_CALL ModuleManager::hasElements()
    throw(css::uno::RuntimeException)
{
    css::uno::Reference< css::container::XNameAccess > xCFG = implts_getConfig();
    return xCFG->hasElements();
}

/*-----------------------------------------------
    07.03.2007 12:55
-----------------------------------------------*/
css::uno::Reference< css::container::XEnumeration > SAL_CALL ModuleManager::createSubSetEnumerationByQuery(const ::rtl::OUString&)
    throw(css::uno::RuntimeException)
{
    return css::uno::Reference< css::container::XEnumeration >();
}

/*-----------------------------------------------
    07.03.2007 12:55
-----------------------------------------------*/
css::uno::Reference< css::container::XEnumeration > SAL_CALL ModuleManager::createSubSetEnumerationByProperties(const css::uno::Sequence< css::beans::NamedValue >& lProperties)
    throw(css::uno::RuntimeException)
{
    ::comphelper::SequenceAsHashMap                 lSearchProps (lProperties);
    css::uno::Sequence< ::rtl::OUString >           lModules     = getElementNames();
    sal_Int32                                       c            = lModules.getLength();
    sal_Int32                                       i            = 0;
    ::comphelper::SequenceAsVector< css::uno::Any > lResult      ;

    for (i=0; i<c; ++i)
    {
        try
        {
            const ::rtl::OUString&                sModule      = lModules[i];
                  ::comphelper::SequenceAsHashMap lModuleProps = getByName(sModule);

            if (lModuleProps.match(lSearchProps))
                lResult.push_back(css::uno::makeAny(lModuleProps.getAsConstPropertyValueList()));
        }
        catch(const css::uno::Exception&)
            {}
    }

    ::comphelper::OAnyEnumeration*                      pEnum = new ::comphelper::OAnyEnumeration(lResult.getAsConstList());
    css::uno::Reference< css::container::XEnumeration > xEnum(static_cast< css::container::XEnumeration* >(pEnum), css::uno::UNO_QUERY_THROW);
    return xEnum;
}

/*-----------------------------------------------
    14.12.2003 09:45
-----------------------------------------------*/
css::uno::Reference< css::container::XNameAccess > ModuleManager::implts_getConfig()
    throw(css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    ReadGuard aReadLock(m_aLock);
    if (m_xCFG.is())
        return m_xCFG;
    css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
    aReadLock.unlock();
    // <- SAFE ----------------------------------

    css::uno::Reference< css::uno::XInterface > xCfg;
    try
    {
        xCfg = ::comphelper::ConfigurationHelper::openConfig(
                    xSMGR,
                    CFGPATH_FACTORIES,
                    ::comphelper::ConfigurationHelper::E_READONLY);
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::uno::Exception&)
        { xCfg.clear(); }

    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);
    m_xCFG = css::uno::Reference< css::container::XNameAccess >(xCfg, css::uno::UNO_QUERY_THROW);
    return m_xCFG;
    // <- SAFE ----------------------------------
}

/*-----------------------------------------------
    30.01.2004 07:54
-----------------------------------------------*/
::rtl::OUString ModuleManager::implts_identify(const css::uno::Reference< css::uno::XInterface >& xComponent)
{
    // Search for an optional (!) interface XModule first.
    // It's used to overrule an existing service name. Used e.g. by our database form designer
    // which uses a writer module internally.
    css::uno::Reference< css::frame::XModule > xModule(xComponent, css::uno::UNO_QUERY);
    if (xModule.is())
        return xModule->getIdentifier();

    // detect modules in a generic way ...
    // comparing service names with configured entries ...
    css::uno::Reference< css::lang::XServiceInfo > xInfo(xComponent, css::uno::UNO_QUERY);
    if (!xInfo.is())
        return ::rtl::OUString();

    const css::uno::Sequence< ::rtl::OUString > lKnownModules = getElementNames();
    const ::rtl::OUString*                      pKnownModules = lKnownModules.getConstArray();
          sal_Int32                             c             = lKnownModules.getLength();
          sal_Int32                             i             = 0;

    for (i=0; i<c; ++i)
    {
        if (xInfo->supportsService(pKnownModules[i]))
            return pKnownModules[i];
    }

    return ::rtl::OUString();
}

} // namespace framework
