/**************************************************************
 * 
 * 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_connectivity.hxx"
#include "connectivity/parameters.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/form/DatabaseParameterEvent.hpp>
#include <com/sun/star/sdbc/XParameters.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/sdb/XParametersSupplier.hpp>
#include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
#include <com/sun/star/sdb/ParametersRequest.hpp>
/** === end UNO includes === **/

#include <connectivity/dbtools.hxx>
#include "connectivity/filtermanager.hxx"
#include "TConnection.hxx"

#include <tools/debug.hxx>
#include <tools/diagnose_ex.h>

#include <comphelper/uno3.hxx>
#include <comphelper/proparrhlp.hxx>
#include <comphelper/broadcasthelper.hxx>
#include "connectivity/ParameterCont.hxx"
#include <rtl/ustrbuf.hxx>

//........................................................................
namespace dbtools
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::sdb;
    using namespace ::com::sun::star::sdbc;
    using namespace ::com::sun::star::sdbcx;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::beans;
    using namespace ::com::sun::star::task;
    using namespace ::com::sun::star::form;
    using namespace ::com::sun::star::container;

    using namespace ::comphelper;
    using namespace ::connectivity;

    //====================================================================
    //= ParameterManager
    //====================================================================
    //--------------------------------------------------------------------
    ParameterManager::ParameterManager( ::osl::Mutex& _rMutex, const Reference< XMultiServiceFactory >& _rxORB )
        :m_rMutex             ( _rMutex )
        ,m_aParameterListeners( _rMutex )
        ,m_xORB               ( _rxORB  )
        ,m_pOuterParameters   ( NULL    )
        ,m_nInnerCount        ( 0       )
        ,m_bUpToDate          ( false   )
    {
        OSL_ENSURE( m_xORB.is(), "ParameterManager::ParameterManager: no service factory!" );
    }

	//--------------------------------------------------------------------
    void ParameterManager::initialize( const Reference< XPropertySet >& _rxComponent, const Reference< XAggregation >& _rxComponentAggregate )
    {
        OSL_ENSURE( !m_xComponent.get().is(), "ParameterManager::initialize: already initialized!" );

        m_xComponent        = _rxComponent;
        m_xAggregatedRowSet = _rxComponentAggregate;
        if ( m_xAggregatedRowSet.is() )
            m_xAggregatedRowSet->queryAggregation( ::getCppuType( &m_xInnerParamUpdate ) ) >>= m_xInnerParamUpdate;
        OSL_ENSURE( m_xComponent.get().is() && m_xInnerParamUpdate.is(), "ParameterManager::initialize: invalid arguments!" );
        if ( !m_xComponent.get().is() || !m_xInnerParamUpdate.is() )
            return;
    }

	//--------------------------------------------------------------------
    void ParameterManager::dispose( )
    {
        clearAllParameterInformation();

        m_xComposer.clear();
        m_xParentComposer.clear();
        //m_xComponent.clear();
        m_xInnerParamUpdate.clear();
		m_xAggregatedRowSet.clear();
    }

    //--------------------------------------------------------------------
    void ParameterManager::clearAllParameterInformation()
    {
       m_xInnerParamColumns.clear();
        if ( m_pOuterParameters.is() )
            m_pOuterParameters->dispose();
        m_pOuterParameters   = NULL;
        m_nInnerCount        = 0;
        ParameterInformation aEmptyInfo;
        m_aParameterInformation.swap( aEmptyInfo );
        m_aMasterFields.realloc( 0 );
        m_aDetailFields.realloc( 0 );
        m_sIdentifierQuoteString = ::rtl::OUString();
        ::std::vector< bool > aEmptyArray;
        m_aParametersVisited.swap( aEmptyArray );
        m_bUpToDate = false;
    }

    //--------------------------------------------------------------------
    void ParameterManager::disposing( const EventObject& /*_rDisposingEvent*/ )
    {
    }

    //--------------------------------------------------------------------
    void ParameterManager::setAllParametersNull() SAL_THROW( ( SQLException, RuntimeException ) )
    {
        OSL_PRECOND( isAlive(), "ParameterManager::setAllParametersNull: not initialized, or already disposed!" );
        if ( !isAlive() )
            return;

        for ( sal_Int32 i = 1; i <= m_nInnerCount; ++i )
			m_xInnerParamUpdate->setNull( i, DataType::VARCHAR );
    }

    //--------------------------------------------------------------------
    bool ParameterManager::initializeComposerByComponent( const Reference< XPropertySet >& _rxComponent )
    {
        OSL_PRECOND( _rxComponent.is(), "ParameterManager::initializeComposerByComponent: invalid !" );

        m_xComposer.clear();
        m_xInnerParamColumns.clear();
        m_nInnerCount = 0;

        // create and fill a composer
        try
        {
            // get a query composer for the 's settings
            m_xComposer.reset( getCurrentSettingsComposer( _rxComponent, m_xORB ), SharedQueryComposer::TakeOwnership );

            // see if the composer found parameters
            Reference< XParametersSupplier > xParamSupp( m_xComposer, UNO_QUERY );
            if ( xParamSupp.is() )
                m_xInnerParamColumns = xParamSupp->getParameters();

            if ( m_xInnerParamColumns.is() )
                m_nInnerCount = m_xInnerParamColumns->getCount();
        }
        catch( const SQLException& )
        {
        }

        return m_xInnerParamColumns.is();
    }

    //--------------------------------------------------------------------
    void ParameterManager::collectInnerParameters( bool _bSecondRun )
    {
        OSL_PRECOND( m_xInnerParamColumns.is(), "ParameterManager::collectInnerParameters: missing some internal data!" );
        if ( !m_xInnerParamColumns.is() )
            return;

        // strip previous index informations
        if ( _bSecondRun )
        {
            for ( ParameterInformation::iterator aParamInfo = m_aParameterInformation.begin();
                  aParamInfo != m_aParameterInformation.end();
                  ++aParamInfo
                )
            {
                aParamInfo->second.aInnerIndexes.clear();
            }
        }

        // we need to map the parameter names (which is all we get from the 's
        // MasterFields property) to indicies, which are needed by the XParameters
        // interface of the row set)
        Reference<XPropertySet> xParam;
        for ( sal_Int32 i = 0; i < m_nInnerCount; ++i )
        {
            try
            {
                xParam.clear();
                m_xInnerParamColumns->getByIndex( i ) >>= xParam;

                ::rtl::OUString sName;
                xParam->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME) ) >>= sName;

                // only append additonal paramters when they are not already in the list
                ParameterInformation::iterator aExistentPos = m_aParameterInformation.find( sName );
                OSL_ENSURE( !_bSecondRun || ( aExistentPos != m_aParameterInformation.end() ),
                    "ParameterManager::collectInnerParameters: the parameter information should already exist in the second run!" );

                if ( aExistentPos == m_aParameterInformation.end() )
                {
                    aExistentPos = m_aParameterInformation.insert( ParameterInformation::value_type(
                        sName, xParam ) ).first;
                }
                else
                    aExistentPos->second.xComposerColumn = xParam;

                aExistentPos->second.aInnerIndexes.push_back( i );
            }
            catch( const Exception& )
            {
                OSL_ENSURE( sal_False, "ParameterManager::collectInnerParameters: caught an exception!" );
            }
        }
    }

    //--------------------------------------------------------------------
    ::rtl::OUString ParameterManager::createFilterConditionFromColumnLink(
        const ::rtl::OUString& _rMasterColumn, const ::rtl::OUString& _rDetailLink, ::rtl::OUString& _rNewParamName )
    {
        ::rtl::OUString sFilter;

        // format is:
        // <detail_column> = :<new_param_name>
        sFilter = quoteName( m_sIdentifierQuoteString, _rDetailLink );
        sFilter += ::rtl::OUString::createFromAscii( " = :" );

        // generate a parameter name which is not already used
        _rNewParamName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "link_from_" ) );
        _rNewParamName += convertName2SQLName( _rMasterColumn, m_sSpecialCharacters );
        while ( m_aParameterInformation.find( _rNewParamName ) != m_aParameterInformation.end() )
        {
            _rNewParamName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_" ) );
        }

        return sFilter += _rNewParamName;
    }

    //--------------------------------------------------------------------
    void ParameterManager::classifyLinks( const Reference< XNameAccess >& _rxParentColumns,
        const Reference< XNameAccess >& _rxColumns, ::std::vector< ::rtl::OUString >& _out_rAdditionalFilterComponents ) SAL_THROW(( Exception ))
    {
        OSL_PRECOND( m_aMasterFields.getLength() == m_aDetailFields.getLength(),
            "ParameterManager::classifyLinks: master and detail fields should have the same length!" );
        OSL_ENSURE( _rxColumns.is(), "ParameterManager::classifyLinks: invalid columns!" );

        if ( !_rxColumns.is() )
            return;

        // we may need to strip any links which are invalid, so here go the containers
        // for temporarirly holding the new pairs
        ::std::vector< ::rtl::OUString > aStrippedMasterFields;
        ::std::vector< ::rtl::OUString > aStrippedDetailFields;

        bool bNeedExchangeLinks = false;

        // classify the links
        const ::rtl::OUString* pMasterFields = m_aMasterFields.getConstArray();
        const ::rtl::OUString* pDetailFields = m_aDetailFields.getConstArray();
        const ::rtl::OUString* pDetailFieldsEnd = pDetailFields + m_aDetailFields.getLength();
        for ( ; pDetailFields < pDetailFieldsEnd; ++pDetailFields, ++pMasterFields )
        {
            if ( !pMasterFields->getLength() || !pDetailFields->getLength() )
                continue;

            // if not even the master part of the relationship exists in the parent , the
            // link is invalid as a whole
            // #i63674# / 2006-03-28 / frank.schoenheit@sun.com
            if ( !_rxParentColumns->hasByName( *pMasterFields ) )
            {
                bNeedExchangeLinks = true;
                continue;
            }

            bool bValidLink = true;

            // is there an inner parameter with this name? That is, a parameter which is already part of
            // the very original statement (not the one we create ourselve, with the additional parameters)
            ParameterInformation::iterator aPos = m_aParameterInformation.find( *pDetailFields );
            if ( aPos != m_aParameterInformation.end() )
            {   // there is an inner parameter with this name
                aPos->second.eType = eLinkedByParamName;
                aStrippedDetailFields.push_back( *pDetailFields );
            }
            else
            {
                // does the detail name denote a column?
                if ( _rxColumns->hasByName( *pDetailFields ) )
                {
                    ::rtl::OUString sNewParamName;
                    const ::rtl::OUString sFilterCondition = createFilterConditionFromColumnLink( *pMasterFields, *pDetailFields, sNewParamName );
                    OSL_PRECOND( sNewParamName.getLength(), "ParameterManager::classifyLinks: createFilterConditionFromColumnLink returned nonsense!" );

                    // remember meta information about this new parameter
                    ::std::pair< ParameterInformation::iterator, bool > aInsertionPos =
                        m_aParameterInformation.insert(
                            ParameterInformation::value_type( sNewParamName, ParameterMetaData( NULL ) )
                        );
                    OSL_ENSURE( aInsertionPos.second, "ParameterManager::classifyLinks: there already was a parameter with this name!" );
                    aInsertionPos.first->second.eType = eLinkedByColumnName;

                    // remember the filter component
                    _out_rAdditionalFilterComponents.push_back( sFilterCondition );

                    // remember the new "detail field" for this link
                    aStrippedDetailFields.push_back( sNewParamName );
                    bNeedExchangeLinks = true;
                }
                else
                {
                    // the detail field neither denotes a column name, nor a parameter name
                    bValidLink = false;
                    bNeedExchangeLinks = true;
                }
            }

            if ( bValidLink )
                aStrippedMasterFields.push_back( *pMasterFields );
        }
        OSL_POSTCOND( aStrippedMasterFields.size() == aStrippedDetailFields.size(),
            "ParameterManager::classifyLinks: inconsistency in new link pairs!" );

        if ( bNeedExchangeLinks )
        {
            ::rtl::OUString *pFields = aStrippedMasterFields.empty() ? 0 : &aStrippedMasterFields[0];
            m_aMasterFields = Sequence< ::rtl::OUString >( pFields, aStrippedMasterFields.size() );
            pFields = aStrippedDetailFields.empty() ? 0 : &aStrippedDetailFields[0];
            m_aDetailFields = Sequence< ::rtl::OUString >( pFields, aStrippedDetailFields.size() );
        }
    }

    //--------------------------------------------------------------------
    void ParameterManager::analyzeFieldLinks( FilterManager& _rFilterManager, bool& /* [out] */ _rColumnsInLinkDetails )
    {
        OSL_PRECOND( isAlive(), "ParameterManager::analyzeFieldLinks: not initialized, or already disposed!" );
        if ( !isAlive() )
            return;

        _rColumnsInLinkDetails = false;
        try
        {
            // the links as determined by the  properties
            Reference< XPropertySet > xProp = m_xComponent;
            OSL_ENSURE(xProp.is(),"Some already released my component!");
            if ( xProp.is() )
            {
                xProp->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MASTERFIELDS) ) >>= m_aMasterFields;
                xProp->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DETAILFIELDS) ) >>= m_aDetailFields;
            }

            {
                // normalize to equal length
                sal_Int32 nMasterLength = m_aMasterFields.getLength();
                sal_Int32 nDetailLength = m_aDetailFields.getLength();

                if ( nMasterLength > nDetailLength )
                    m_aMasterFields.realloc( nDetailLength );
                else if ( nDetailLength > nMasterLength )
                    m_aDetailFields.realloc( nMasterLength );
            }

            Reference< XNameAccess > xColumns;
            if ( !getColumns( xColumns, true ) )
                // already asserted in getColumns
                return;

            Reference< XNameAccess > xParentColumns;
            if ( !getParentColumns( xParentColumns, true ) )
                return;

            // classify the links - depending on what the detail fields in each link pair denotes
            ::std::vector< ::rtl::OUString > aAdditionalFilterComponents;
            classifyLinks( xParentColumns, xColumns, aAdditionalFilterComponents );

            // did we find links where the detail field refers to a detail column (instead of a parameter name)?
            if ( !aAdditionalFilterComponents.empty() )
            {
                const static ::rtl::OUString s_sAnd( RTL_CONSTASCII_USTRINGPARAM( " AND " ) );
                // build a conjunction of all the filter components
                ::rtl::OUStringBuffer sAdditionalFilter;
                for (   ::std::vector< ::rtl::OUString >::const_iterator aComponent = aAdditionalFilterComponents.begin();
                        aComponent != aAdditionalFilterComponents.end();
                        ++aComponent
                    )
                {
                    if ( sAdditionalFilter.getLength() )
                        sAdditionalFilter.append(s_sAnd);
                    
                    sAdditionalFilter.appendAscii("( ",((sal_Int32)(sizeof("( ")-1)));
                    sAdditionalFilter.append(*aComponent);
                    sAdditionalFilter.appendAscii(" )",((sal_Int32)(sizeof(" )")-1)));
                }

                // now set this filter at the 's filter manager
                _rFilterManager.setFilterComponent( FilterManager::fcLinkFilter, sAdditionalFilter.makeStringAndClear() );

                _rColumnsInLinkDetails = true;
            }
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "ParameterManager::analyzeFieldLinks: caught an exception!" );
        }
    }

    //--------------------------------------------------------------------
    void ParameterManager::createOuterParameters()
    {
        OSL_PRECOND( !m_pOuterParameters.is(), "ParameterManager::createOuterParameters: outer parameters not initialized!" );
        OSL_PRECOND( m_xInnerParamUpdate.is(), "ParameterManager::createOuterParameters: no write access to the inner parameters!" );
        if ( !m_xInnerParamUpdate.is() )
            return;

        m_pOuterParameters = new param::ParameterWrapperContainer;

#if OSL_DEBUG_LEVEL > 0
        sal_Int32 nSmallestIndexLinkedByColumnName = -1;
        sal_Int32 nLargestIndexNotLinkedByColumnName = -1;
#endif
        ::rtl::OUString sName;
        for ( ParameterInformation::iterator aParam = m_aParameterInformation.begin();
              aParam != m_aParameterInformation.end();
              ++aParam
            )
        {
#if OSL_DEBUG_LEVEL > 0
            if ( aParam->second.aInnerIndexes.size() )
                if ( aParam->second.eType == eLinkedByColumnName )
                {
                    if ( nSmallestIndexLinkedByColumnName == -1 )
                        nSmallestIndexLinkedByColumnName = aParam->second.aInnerIndexes[ 0 ];
                }
                else
                {
                    nLargestIndexNotLinkedByColumnName = aParam->second.aInnerIndexes[ aParam->second.aInnerIndexes.size() - 1 ];
                }
#endif
            if ( aParam->second.eType != eFilledExternally )
                continue;

            // check which of the parameters have already been visited (e.g. filled via XParameters)
            size_t nAlreadyVisited = 0;
            for (   ::std::vector< sal_Int32 >::iterator aIndex = aParam->second.aInnerIndexes.begin();
                    aIndex != aParam->second.aInnerIndexes.end();
                    ++aIndex
                )
            {
                if ( ( m_aParametersVisited.size() > (size_t)*aIndex ) && m_aParametersVisited[ *aIndex ] )
                {   // exclude this index
                    *aIndex = -1;
                    ++nAlreadyVisited;
                }
            }
            if ( nAlreadyVisited == aParam->second.aInnerIndexes.size() )
                continue;

            // need a wrapper for this .... the "inner parameters" as supplied by a result set don't have a "Value"
            // property, but the parameter listeners expect such a property. So we need an object "aggregating"
            // xParam and supplying an additional property ("Value")
            // (it's no real aggregation of course ...)
            m_pOuterParameters->push_back( new param::ParameterWrapper( aParam->second.xComposerColumn, m_xInnerParamUpdate, aParam->second.aInnerIndexes ) );
        }

#if OSL_DEBUG_LEVEL > 0
        OSL_ENSURE( ( nSmallestIndexLinkedByColumnName == -1 ) || ( nLargestIndexNotLinkedByColumnName == -1 ) ||
            ( nSmallestIndexLinkedByColumnName > nLargestIndexNotLinkedByColumnName ),
            "ParameterManager::createOuterParameters: inconsistency!" );

        // for the master-detail links, where the detail field denoted a column name, we created an addtional ("artificial")
        // filter, and *appended* it to all other (potentially) existing filters of the row set. This means that the indexes
        // for the parameters resulting from the artifical filter should be larger than any other parameter index, and this
        // is what the assertion checks.
        // If the assertion fails, then we would need another handling for the "parameters visited" flags, since they're based
        // on parameter indexes *without* the artificial filter (because this filter is not visible from the outside).
#endif
    }

    //--------------------------------------------------------------------
    void ParameterManager::updateParameterInfo( FilterManager& _rFilterManager )
    {
        OSL_PRECOND( isAlive(), "ParameterManager::updateParameterInfo: not initialized, or already disposed!" );
        if ( !isAlive() )
            return;

        clearAllParameterInformation();
        cacheConnectionInfo();

        // check whether the  is based on a statement/query which requires parameters
        Reference< XPropertySet > xProp = m_xComponent;
        OSL_ENSURE(xProp.is(),"Some already released my component!");
        if ( xProp.is() )
        {
            if ( !initializeComposerByComponent( xProp ) )
            {   // okay, nothing to do
                m_bUpToDate = true;
                return;
            } // if ( !initializeComposerByComponent( m_xComponent ) )
        }
        OSL_POSTCOND( m_xInnerParamColumns.is(), "ParameterManager::updateParameterInfo: initializeComposerByComponent did nonsense (1)!" );

        // collect all parameters which are defined by the "inner parameters"
        collectInnerParameters( false );

        // analyze the master-detail relationships
        bool bColumnsInLinkDetails = false;
        analyzeFieldLinks( _rFilterManager, bColumnsInLinkDetails );

        if ( bColumnsInLinkDetails )
        {
            // okay, in this case, analyzeFieldLinks modified the "real" filter at the RowSet, to contain
            // an additional restriction (which we created ourself)
            // So we need to update all information about our inner parameter columns
            Reference< XPropertySet > xDirectRowSetProps;
            m_xAggregatedRowSet->queryAggregation( ::getCppuType( &xDirectRowSetProps ) ) >>= xDirectRowSetProps;
            OSL_VERIFY( initializeComposerByComponent( xDirectRowSetProps ) );
            collectInnerParameters( true );
        }

        if ( !m_nInnerCount )
        {   // no parameters at all
            m_bUpToDate = true;
            return;
        }

        // for what now remains as outer parameters, create the wrappers for the single
        // parameter columns
        createOuterParameters();

        m_bUpToDate = true;
    }

    //--------------------------------------------------------------------
    void ParameterManager::fillLinkedParameters( const Reference< XNameAccess >& _rxParentColumns )
    {
        OSL_PRECOND( isAlive(), "ParameterManager::fillLinkedParameters: not initialized, or already disposed!" );
        if ( !isAlive() )
            return;
        OSL_PRECOND( m_xInnerParamColumns.is(), "ParameterManager::fillLinkedParameters: no inner parameters found!"                 );
        OSL_ENSURE ( _rxParentColumns.is(),     "ParameterManager::fillLinkedParameters: invalid parent columns!"                    );

        try
        {
            // the master and detail field( name)s of the 
            const ::rtl::OUString* pMasterFields = m_aMasterFields.getConstArray();
            const ::rtl::OUString* pDetailFields = m_aDetailFields.getConstArray();

            sal_Int32 nMasterLen = m_aMasterFields.getLength();
			Any aParamType, aScale, aValue;

            // loop through all master fields. For each of them, get the respective column from the
            // parent , and forward it's current value as paramter value to the (inner) row set
            for ( sal_Int32 i = 0; i < nMasterLen; ++i, ++pMasterFields, ++pDetailFields )
			{
                // does the name denote a valid column in the parent?
                if ( !_rxParentColumns->hasByName( *pMasterFields ) )
                {
                    OSL_ENSURE( sal_False, "ParameterManager::fillLinkedParameters: invalid master names should have been stripped long before!" );
                    continue;
                }

                // do we, for this name, know where to place the values?
                ParameterInformation::const_iterator aParamInfo = m_aParameterInformation.find( *pDetailFields );
                if  (  ( aParamInfo == m_aParameterInformation.end() )
                    || ( aParamInfo->second.aInnerIndexes.empty() )
                    )
                {
                    OSL_ENSURE( sal_False, "ParameterManager::fillLinkedParameters: nothing known about this detail field!" );
                    continue;
                }

                // the concrete master field
                Reference< XPropertySet >  xMasterField(_rxParentColumns->getByName( *pMasterFields ),UNO_QUERY);

                // the positions where we have to fill in values for the current parameter name
                for ( ::std::vector< sal_Int32 >::const_iterator aPosition = aParamInfo->second.aInnerIndexes.begin();
                      aPosition != aParamInfo->second.aInnerIndexes.end();
                      ++aPosition
                    )
                {
                    // the concrete detail field
                    Reference< XPropertySet >  xDetailField(m_xInnerParamColumns->getByIndex( *aPosition ),UNO_QUERY);
                    OSL_ENSURE( xDetailField.is(), "ParameterManager::fillLinkedParameters: invalid detail field!" );
                    if ( !xDetailField.is() )
                        continue;

					// type and scale of the parameter field
                    sal_Int32 nParamType = DataType::VARCHAR;
					OSL_VERIFY( xDetailField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE) ) >>= nParamType );

                    sal_Int32 nScale = 0;
					if ( xDetailField->getPropertySetInfo()->hasPropertyByName( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE) ) )
						OSL_VERIFY( xDetailField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE) ) >>= nScale );

					// transfer the param value
					try
					{
						m_xInnerParamUpdate->setObjectWithInfo(
                            *aPosition + 1,                     // parameters are based at 1
                            xMasterField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_VALUE) ),
                            nParamType,
                            nScale
                        );
					}
					catch( const Exception& )
					{
						OSL_ENSURE( sal_False,
								    ::rtl::OString( "ParameterManager::fillLinkedParameters: master-detail parameter number " )
								+=	::rtl::OString::valueOf( sal_Int32( *aPosition + 1 ) )
                                +=  ::rtl::OString( " could not be filled!" ) );
					}
                }
			}
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }

    //--------------------------------------------------------------------
    bool ParameterManager::completeParameters( const Reference< XInteractionHandler >& _rxCompletionHandler, const Reference< XConnection > _rxConnection )
    {
        OSL_PRECOND( isAlive(), "ParameterManager::completeParameters: not initialized, or already disposed!" );
        OSL_ENSURE ( _rxCompletionHandler.is(), "ParameterManager::completeParameters: invalid interaction handler!" );

		// two continuations (Ok and Cancel)
        OInteractionAbort* pAbort = new OInteractionAbort;
		OParameterContinuation* pParams = new OParameterContinuation;

		// the request
		ParametersRequest aRequest;
		aRequest.Parameters = m_pOuterParameters.get();
		aRequest.Connection = _rxConnection;
		OInteractionRequest* pRequest = new OInteractionRequest( makeAny( aRequest ) );
		Reference< XInteractionRequest > xRequest( pRequest );

		// some knittings
		pRequest->addContinuation( pAbort );
		pRequest->addContinuation( pParams );

		// execute the request
        try
        {
    		_rxCompletionHandler->handle( xRequest );
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "ParameterManager::completeParameters: caught an exception while calling the handler!" );
        }

		if ( !pParams->wasSelected() )
			// canceled by the user (i.e. (s)he canceled the dialog)
			return false;

        try
        {
		    // transfer the values from the continuation object to the parameter columns
		    Sequence< PropertyValue > aFinalValues = pParams->getValues();
		    const PropertyValue* pFinalValues = aFinalValues.getConstArray();
		    for ( sal_Int32 i = 0; i < aFinalValues.getLength(); ++i, ++pFinalValues )
		    {
                Reference< XPropertySet > xParamColumn(aRequest.Parameters->getByIndex( i ),UNO_QUERY);
			    if ( xParamColumn.is() )
			    {
            #ifdef DBG_UTIL
				    ::rtl::OUString sName;
				    xParamColumn->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME) ) >>= sName;
				    OSL_ENSURE( sName == pFinalValues->Name, "ParameterManager::completeParameters: inconsistent parameter names!" );
            #endif
				    xParamColumn->setPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_VALUE), pFinalValues->Value );
					    // the property sets are wrapper classes, translating the Value property into a call to
					    // the appropriate XParameters interface
			    }
		    }
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "ParameterManager::completeParameters: caught an exception while propagating the values!" );
        }
        return true;
    }

    //--------------------------------------------------------------------
    bool ParameterManager::consultParameterListeners( ::osl::ResettableMutexGuard& _rClearForNotifies )
    {
	    bool bCanceled = false;

        sal_Int32 nParamsLeft = m_pOuterParameters->getParameters().size();
            // TODO: shouldn't we subtract all the parameters which were already visited?
		if ( nParamsLeft )
		{
			::cppu::OInterfaceIteratorHelper aIter( m_aParameterListeners );
            Reference< XPropertySet > xProp = m_xComponent;
            OSL_ENSURE(xProp.is(),"Some already released my component!");
			DatabaseParameterEvent aEvent( xProp.get(), m_pOuterParameters.get() );

            _rClearForNotifies.clear();
			while ( aIter.hasMoreElements() && !bCanceled )
				bCanceled = !static_cast< XDatabaseParameterListener* >( aIter.next() )->approveParameter( aEvent );
			_rClearForNotifies.reset();
		}

        return !bCanceled;
    }

    //--------------------------------------------------------------------
    bool ParameterManager::fillParameterValues( const Reference< XInteractionHandler >& _rxCompletionHandler, ::osl::ResettableMutexGuard& _rClearForNotifies )
    {
        OSL_PRECOND( isAlive(), "ParameterManager::fillParameterValues: not initialized, or already disposed!" );
        if ( !isAlive() )
            return true;

        if ( m_nInnerCount == 0 )
            // no parameters at all
		    return true;

        // fill the parameters from the master-detail relationship
        Reference< XNameAccess > xParentColumns;
        if ( getParentColumns( xParentColumns, false ) && xParentColumns->hasElements() && m_aMasterFields.getLength() )
            fillLinkedParameters( xParentColumns );

        // let the user (via the interaction handler) fill all remaining parameters
        Reference< XConnection > xConnection;
        getConnection( xConnection );

        if ( _rxCompletionHandler.is() )
            return completeParameters( _rxCompletionHandler, xConnection );

        return consultParameterListeners( _rClearForNotifies );
    }

    //--------------------------------------------------------------------
    bool ParameterManager::getConnection( Reference< XConnection >& /* [out] */ _rxConnection )
    {
        OSL_PRECOND( isAlive(), "ParameterManager::getConnection: not initialized, or already disposed!" );
        if ( !isAlive() )
            return false;

        _rxConnection.clear();
        try
        {
            Reference< XPropertySet > xProp = m_xComponent;
            OSL_ENSURE(xProp.is(),"Some already released my component!");
            if ( xProp.is() )
                xProp->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ACTIVE_CONNECTION) ) >>= _rxConnection;
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "ParameterManager::getConnection: could not retrieve the connection of the !" );
        }
        return _rxConnection.is();
    }

    //--------------------------------------------------------------------
    void ParameterManager::cacheConnectionInfo() SAL_THROW(( ))
    {
        try
        {
            Reference< XConnection > xConnection;
            getConnection( xConnection );
            Reference< XDatabaseMetaData > xMeta;
            if ( xConnection.is() )
                xMeta = xConnection->getMetaData();
            if ( xMeta.is() )
            {
                m_sIdentifierQuoteString = xMeta->getIdentifierQuoteString();
                m_sSpecialCharacters = xMeta->getExtraNameCharacters();
            }
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "ParameterManager::cacheConnectionInfo: caught an exception!" );
        }
    }

    //--------------------------------------------------------------------
    bool ParameterManager::getColumns( Reference< XNameAccess >& /* [out] */ _rxColumns, bool _bFromComposer ) SAL_THROW(( Exception ))
    {
        _rxColumns.clear();

        Reference< XColumnsSupplier > xColumnSupp;
        if ( _bFromComposer )
            xColumnSupp = xColumnSupp.query( m_xComposer );
        else
            xColumnSupp.set( m_xComponent.get(),UNO_QUERY);
        if ( xColumnSupp.is() )
            _rxColumns = xColumnSupp->getColumns();
        OSL_ENSURE( _rxColumns.is(), "ParameterManager::getColumns: could not retrieve the columns for the detail !" );

        return _rxColumns.is();
    }

    //--------------------------------------------------------------------
    bool ParameterManager::getParentColumns( Reference< XNameAccess >& /* [out] */ _out_rxParentColumns, bool _bFromComposer )
    {
        OSL_PRECOND( isAlive(), "ParameterManager::getParentColumns: not initialized, or already disposed!" );

        _out_rxParentColumns.clear();
        try
        {
            // get the parent of the component we're working for
            Reference< XChild > xAsChild( m_xComponent.get(), UNO_QUERY_THROW );
            Reference< XPropertySet > xParent( xAsChild->getParent(), UNO_QUERY );
            if ( !xParent.is() )
                return false;

            // the columns supplier: either from a composer, or directly from the 
            Reference< XColumnsSupplier > xParentColSupp;
            if ( _bFromComposer )
            {
                // re-create the parent composer all the time. Else, we'd have to bother with
                // being a listener at its properties, its loaded state, and event the parent-relationship.
                m_xParentComposer.reset(
                    getCurrentSettingsComposer( xParent, m_xORB ),
                    SharedQueryComposer::TakeOwnership
                );
                xParentColSupp = xParentColSupp.query( m_xParentComposer );
            }
            else
                xParentColSupp = xParentColSupp.query( xParent );

            // get the columns of the parent 
            if ( xParentColSupp.is() )
                _out_rxParentColumns = xParentColSupp->getColumns();
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "ParameterManager::getParentColumns: caught an exception!" );
        }
        return _out_rxParentColumns.is();
    }

    //--------------------------------------------------------------------
    void ParameterManager::addParameterListener( const Reference< XDatabaseParameterListener >& _rxListener )
    {
        if ( _rxListener.is() )
            m_aParameterListeners.addInterface( _rxListener );
    }

    //--------------------------------------------------------------------
    void ParameterManager::removeParameterListener( const Reference< XDatabaseParameterListener >& _rxListener )
    {
        m_aParameterListeners.removeInterface( _rxListener );
    }

    //--------------------------------------------------------------------
    void ParameterManager::resetParameterValues( ) SAL_THROW(())
    {
        OSL_PRECOND( isAlive(), "ParameterManager::resetParameterValues: not initialized, or already disposed!" );
        if ( !isAlive() )
            return;

        if ( !m_nInnerCount )
            // no parameters at all
            return;

        try
        {
            Reference< XNameAccess > xColumns;
            if ( !getColumns( xColumns, false ) )
                // already asserted in getColumns
                return;

		    Reference< XNameAccess > xParentColumns;
            if ( !getParentColumns( xParentColumns, false ) )
                return;

            // loop through all links pairs
		    const ::rtl::OUString* pMasterFields = m_aMasterFields.getConstArray();
		    const ::rtl::OUString* pDetailFields = m_aDetailFields.getConstArray();

            Reference< XPropertySet > xMasterField;
            Reference< XPropertySet > xDetailField;

            // now really ....
		    const ::rtl::OUString* pDetailFieldsEnd = pDetailFields + m_aDetailFields.getLength();
		    for ( ; pDetailFields < pDetailFieldsEnd; ++pDetailFields, ++pMasterFields )
		    {
                if ( !xParentColumns->hasByName( *pMasterFields ) )
                {
                    // if this name is unknown in the parent columns, then we don't have a source
                    // for copying the value to the detail columns
                    OSL_ENSURE( sal_False, "ParameterManager::resetParameterValues: this should have been stripped long before!" );
                    continue;
                }

                // for all inner parameters which are bound to the name as specified by the
                // slave element of the link, propagate the value from the master column to this
                // parameter column
                ParameterInformation::const_iterator aParamInfo = m_aParameterInformation.find( *pDetailFields );
                if  (  ( aParamInfo == m_aParameterInformation.end() )
                    || ( aParamInfo->second.aInnerIndexes.empty() )
                    )
                {
                    OSL_ENSURE( sal_False, "ParameterManager::resetParameterValues: nothing known about this detail field!" );
                    continue;
                }

                xParentColumns->getByName( *pMasterFields ) >>= xMasterField;
                if ( !xMasterField.is() )
                    continue;

                for ( ::std::vector< sal_Int32 >::const_iterator aPosition = aParamInfo->second.aInnerIndexes.begin();
                      aPosition != aParamInfo->second.aInnerIndexes.end();
                      ++aPosition
                    )
                {
				    Reference< XPropertySet > xInnerParameter;
					m_xInnerParamColumns->getByIndex( *aPosition ) >>= xInnerParameter;
                    if ( !xInnerParameter.is() )
                        continue;

                    ::rtl::OUString sParamColumnRealName;
					xInnerParameter->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME) ) >>= sParamColumnRealName;
					if ( xColumns->hasByName( sParamColumnRealName ) )
					{	// our own columns have a column which's name equals the real name of the param column
						// -> transfer the value property
						xColumns->getByName( sParamColumnRealName ) >>= xDetailField;
						if ( xDetailField.is() )
							xDetailField->setPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_VALUE), xMasterField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_VALUE) ) );
					}
                }
		    }
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "ParameterManager::resetParameterValues: caught an exception!" );
        }

    }

    //--------------------------------------------------------------------
    void ParameterManager::externalParameterVisited( sal_Int32 _nIndex )
    {
		if ( m_aParametersVisited.size() < (size_t)_nIndex )
		{
			m_aParametersVisited.reserve( _nIndex );
			for ( sal_Int32 i = m_aParametersVisited.size(); i < _nIndex; ++i )
				m_aParametersVisited.push_back( false );
		}
		m_aParametersVisited[ _nIndex - 1 ] = true;
    }

#define VISIT_PARAMETER( method ) \
        ::osl::MutexGuard aGuard( m_rMutex ); \
        OSL_ENSURE( m_xInnerParamUpdate.is(), "ParameterManager::XParameters::setXXX: no XParameters access to the RowSet!" ); \
        if ( !m_xInnerParamUpdate.is() ) \
            return; \
        m_xInnerParamUpdate->method; \
        externalParameterVisited( _nIndex ) \

    //--------------------------------------------------------------------
    void ParameterManager::setNull( sal_Int32 _nIndex, sal_Int32 sqlType )
	{
        VISIT_PARAMETER( setNull( _nIndex, sqlType ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setObjectNull( sal_Int32 _nIndex, sal_Int32 sqlType, const ::rtl::OUString& typeName )
	{
        VISIT_PARAMETER( setObjectNull( _nIndex, sqlType, typeName ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setBoolean( sal_Int32 _nIndex, sal_Bool x )
	{
        VISIT_PARAMETER( setBoolean( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setByte( sal_Int32 _nIndex, sal_Int8 x )
	{
        VISIT_PARAMETER( setByte( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setShort( sal_Int32 _nIndex, sal_Int16 x )
	{
        VISIT_PARAMETER( setShort( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setInt( sal_Int32 _nIndex, sal_Int32 x )
	{
        VISIT_PARAMETER( setInt( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setLong( sal_Int32 _nIndex, sal_Int64 x )
	{
        VISIT_PARAMETER( setLong( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setFloat( sal_Int32 _nIndex, float x )
	{
        VISIT_PARAMETER( setFloat( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setDouble( sal_Int32 _nIndex, double x )
	{
        VISIT_PARAMETER( setDouble( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setString( sal_Int32 _nIndex, const ::rtl::OUString& x )
	{
        VISIT_PARAMETER( setString( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setBytes( sal_Int32 _nIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x )
	{
        VISIT_PARAMETER( setBytes( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setDate( sal_Int32 _nIndex, const ::com::sun::star::util::Date& x )
	{
        VISIT_PARAMETER( setDate( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setTime( sal_Int32 _nIndex, const ::com::sun::star::util::Time& x )
	{
        VISIT_PARAMETER( setTime( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setTimestamp( sal_Int32 _nIndex, const ::com::sun::star::util::DateTime& x )
	{
        VISIT_PARAMETER( setTimestamp( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setBinaryStream( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, sal_Int32 length )
	{
        VISIT_PARAMETER( setBinaryStream( _nIndex, x, length ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setCharacterStream( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, sal_Int32 length )
	{
        VISIT_PARAMETER( setCharacterStream( _nIndex, x, length ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setObject( sal_Int32 _nIndex, const ::com::sun::star::uno::Any& x )
	{
        VISIT_PARAMETER( setObject( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setObjectWithInfo( sal_Int32 _nIndex, const ::com::sun::star::uno::Any& x, sal_Int32 targetSqlType, sal_Int32 scale )
	{
        VISIT_PARAMETER( setObjectWithInfo( _nIndex, x, targetSqlType, scale ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setRef( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRef>& x )
	{
        VISIT_PARAMETER( setRef( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setBlob( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XBlob>& x )
	{
        VISIT_PARAMETER( setBlob( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setClob( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XClob>& x )
	{
        VISIT_PARAMETER( setClob( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::setArray( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XArray>& x )
	{
        VISIT_PARAMETER( setArray( _nIndex, x ) );
	}

    //--------------------------------------------------------------------
    void ParameterManager::clearParameters( )
	{
        if ( m_xInnerParamUpdate.is() )
            m_xInnerParamUpdate->clearParameters( );
    }

    //====================================================================
    //= OParameterContinuation
    //====================================================================
    //--------------------------------------------------------------------
    void SAL_CALL OParameterContinuation::setParameters( const Sequence< PropertyValue >& _rValues ) throw( RuntimeException )
    {
	    m_aValues = _rValues;
    }

//........................................................................
}   // namespace frm
//........................................................................

