1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_connectivity.hxx"
30 #include "connectivity/parameters.hxx"
31 
32 /** === begin UNO includes === **/
33 #include <com/sun/star/form/DatabaseParameterEvent.hpp>
34 #include <com/sun/star/sdbc/XParameters.hpp>
35 #include <com/sun/star/container/XChild.hpp>
36 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
37 #include <com/sun/star/container/XEnumerationAccess.hpp>
38 #include <com/sun/star/sdb/XParametersSupplier.hpp>
39 #include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
40 #include <com/sun/star/sdb/ParametersRequest.hpp>
41 /** === end UNO includes === **/
42 
43 #include <connectivity/dbtools.hxx>
44 #include "connectivity/filtermanager.hxx"
45 #include "TConnection.hxx"
46 
47 #include <tools/debug.hxx>
48 #include <tools/diagnose_ex.h>
49 
50 #include <comphelper/uno3.hxx>
51 #include <comphelper/proparrhlp.hxx>
52 #include <comphelper/broadcasthelper.hxx>
53 #include "connectivity/ParameterCont.hxx"
54 #include <rtl/ustrbuf.hxx>
55 
56 //........................................................................
57 namespace dbtools
58 {
59 //........................................................................
60 
61     using namespace ::com::sun::star::uno;
62     using namespace ::com::sun::star::sdb;
63     using namespace ::com::sun::star::sdbc;
64     using namespace ::com::sun::star::sdbcx;
65     using namespace ::com::sun::star::lang;
66     using namespace ::com::sun::star::beans;
67     using namespace ::com::sun::star::task;
68     using namespace ::com::sun::star::form;
69     using namespace ::com::sun::star::container;
70 
71     using namespace ::comphelper;
72     using namespace ::connectivity;
73 
74     //====================================================================
75     //= ParameterManager
76     //====================================================================
77     //--------------------------------------------------------------------
78     ParameterManager::ParameterManager( ::osl::Mutex& _rMutex, const Reference< XMultiServiceFactory >& _rxORB )
79         :m_rMutex             ( _rMutex )
80         ,m_aParameterListeners( _rMutex )
81         ,m_xORB               ( _rxORB  )
82         ,m_pOuterParameters   ( NULL    )
83         ,m_nInnerCount        ( 0       )
84         ,m_bUpToDate          ( false   )
85     {
86         OSL_ENSURE( m_xORB.is(), "ParameterManager::ParameterManager: no service factory!" );
87     }
88 
89 	//--------------------------------------------------------------------
90     void ParameterManager::initialize( const Reference< XPropertySet >& _rxComponent, const Reference< XAggregation >& _rxComponentAggregate )
91     {
92         OSL_ENSURE( !m_xComponent.get().is(), "ParameterManager::initialize: already initialized!" );
93 
94         m_xComponent        = _rxComponent;
95         m_xAggregatedRowSet = _rxComponentAggregate;
96         if ( m_xAggregatedRowSet.is() )
97             m_xAggregatedRowSet->queryAggregation( ::getCppuType( &m_xInnerParamUpdate ) ) >>= m_xInnerParamUpdate;
98         OSL_ENSURE( m_xComponent.get().is() && m_xInnerParamUpdate.is(), "ParameterManager::initialize: invalid arguments!" );
99         if ( !m_xComponent.get().is() || !m_xInnerParamUpdate.is() )
100             return;
101     }
102 
103 	//--------------------------------------------------------------------
104     void ParameterManager::dispose( )
105     {
106         clearAllParameterInformation();
107 
108         m_xComposer.clear();
109         m_xParentComposer.clear();
110         //m_xComponent.clear();
111         m_xInnerParamUpdate.clear();
112 		m_xAggregatedRowSet.clear();
113     }
114 
115     //--------------------------------------------------------------------
116     void ParameterManager::clearAllParameterInformation()
117     {
118        m_xInnerParamColumns.clear();
119         if ( m_pOuterParameters.is() )
120             m_pOuterParameters->dispose();
121         m_pOuterParameters   = NULL;
122         m_nInnerCount        = 0;
123         ParameterInformation aEmptyInfo;
124         m_aParameterInformation.swap( aEmptyInfo );
125         m_aMasterFields.realloc( 0 );
126         m_aDetailFields.realloc( 0 );
127         m_sIdentifierQuoteString = ::rtl::OUString();
128         ::std::vector< bool > aEmptyArray;
129         m_aParametersVisited.swap( aEmptyArray );
130         m_bUpToDate = false;
131     }
132 
133     //--------------------------------------------------------------------
134     void ParameterManager::disposing( const EventObject& /*_rDisposingEvent*/ )
135     {
136     }
137 
138     //--------------------------------------------------------------------
139     void ParameterManager::setAllParametersNull() SAL_THROW( ( SQLException, RuntimeException ) )
140     {
141         OSL_PRECOND( isAlive(), "ParameterManager::setAllParametersNull: not initialized, or already disposed!" );
142         if ( !isAlive() )
143             return;
144 
145         for ( sal_Int32 i = 1; i <= m_nInnerCount; ++i )
146 			m_xInnerParamUpdate->setNull( i, DataType::VARCHAR );
147     }
148 
149     //--------------------------------------------------------------------
150     bool ParameterManager::initializeComposerByComponent( const Reference< XPropertySet >& _rxComponent )
151     {
152         OSL_PRECOND( _rxComponent.is(), "ParameterManager::initializeComposerByComponent: invalid !" );
153 
154         m_xComposer.clear();
155         m_xInnerParamColumns.clear();
156         m_nInnerCount = 0;
157 
158         // create and fill a composer
159         try
160         {
161             // get a query composer for the 's settings
162             m_xComposer.reset( getCurrentSettingsComposer( _rxComponent, m_xORB ), SharedQueryComposer::TakeOwnership );
163 
164             // see if the composer found parameters
165             Reference< XParametersSupplier > xParamSupp( m_xComposer, UNO_QUERY );
166             if ( xParamSupp.is() )
167                 m_xInnerParamColumns = xParamSupp->getParameters();
168 
169             if ( m_xInnerParamColumns.is() )
170                 m_nInnerCount = m_xInnerParamColumns->getCount();
171         }
172         catch( const SQLException& )
173         {
174         }
175 
176         return m_xInnerParamColumns.is();
177     }
178 
179     //--------------------------------------------------------------------
180     void ParameterManager::collectInnerParameters( bool _bSecondRun )
181     {
182         OSL_PRECOND( m_xInnerParamColumns.is(), "ParameterManager::collectInnerParameters: missing some internal data!" );
183         if ( !m_xInnerParamColumns.is() )
184             return;
185 
186         // strip previous index informations
187         if ( _bSecondRun )
188         {
189             for ( ParameterInformation::iterator aParamInfo = m_aParameterInformation.begin();
190                   aParamInfo != m_aParameterInformation.end();
191                   ++aParamInfo
192                 )
193             {
194                 aParamInfo->second.aInnerIndexes.clear();
195             }
196         }
197 
198         // we need to map the parameter names (which is all we get from the 's
199         // MasterFields property) to indicies, which are needed by the XParameters
200         // interface of the row set)
201         Reference<XPropertySet> xParam;
202         for ( sal_Int32 i = 0; i < m_nInnerCount; ++i )
203         {
204             try
205             {
206                 xParam.clear();
207                 m_xInnerParamColumns->getByIndex( i ) >>= xParam;
208 
209                 ::rtl::OUString sName;
210                 xParam->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME) ) >>= sName;
211 
212                 // only append additonal paramters when they are not already in the list
213                 ParameterInformation::iterator aExistentPos = m_aParameterInformation.find( sName );
214                 OSL_ENSURE( !_bSecondRun || ( aExistentPos != m_aParameterInformation.end() ),
215                     "ParameterManager::collectInnerParameters: the parameter information should already exist in the second run!" );
216 
217                 if ( aExistentPos == m_aParameterInformation.end() )
218                 {
219                     aExistentPos = m_aParameterInformation.insert( ParameterInformation::value_type(
220                         sName, xParam ) ).first;
221                 }
222                 else
223                     aExistentPos->second.xComposerColumn = xParam;
224 
225                 aExistentPos->second.aInnerIndexes.push_back( i );
226             }
227             catch( const Exception& )
228             {
229                 OSL_ENSURE( sal_False, "ParameterManager::collectInnerParameters: caught an exception!" );
230             }
231         }
232     }
233 
234     //--------------------------------------------------------------------
235     ::rtl::OUString ParameterManager::createFilterConditionFromColumnLink(
236         const ::rtl::OUString& _rMasterColumn, const ::rtl::OUString& _rDetailLink, ::rtl::OUString& _rNewParamName )
237     {
238         ::rtl::OUString sFilter;
239 
240         // format is:
241         // <detail_column> = :<new_param_name>
242         sFilter = quoteName( m_sIdentifierQuoteString, _rDetailLink );
243         sFilter += ::rtl::OUString::createFromAscii( " = :" );
244 
245         // generate a parameter name which is not already used
246         _rNewParamName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "link_from_" ) );
247         _rNewParamName += convertName2SQLName( _rMasterColumn, m_sSpecialCharacters );
248         while ( m_aParameterInformation.find( _rNewParamName ) != m_aParameterInformation.end() )
249         {
250             _rNewParamName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_" ) );
251         }
252 
253         return sFilter += _rNewParamName;
254     }
255 
256     //--------------------------------------------------------------------
257     void ParameterManager::classifyLinks( const Reference< XNameAccess >& _rxParentColumns,
258         const Reference< XNameAccess >& _rxColumns, ::std::vector< ::rtl::OUString >& _out_rAdditionalFilterComponents ) SAL_THROW(( Exception ))
259     {
260         OSL_PRECOND( m_aMasterFields.getLength() == m_aDetailFields.getLength(),
261             "ParameterManager::classifyLinks: master and detail fields should have the same length!" );
262         OSL_ENSURE( _rxColumns.is(), "ParameterManager::classifyLinks: invalid columns!" );
263 
264         if ( !_rxColumns.is() )
265             return;
266 
267         // we may need to strip any links which are invalid, so here go the containers
268         // for temporarirly holding the new pairs
269         ::std::vector< ::rtl::OUString > aStrippedMasterFields;
270         ::std::vector< ::rtl::OUString > aStrippedDetailFields;
271 
272         bool bNeedExchangeLinks = false;
273 
274         // classify the links
275         const ::rtl::OUString* pMasterFields = m_aMasterFields.getConstArray();
276         const ::rtl::OUString* pDetailFields = m_aDetailFields.getConstArray();
277         const ::rtl::OUString* pDetailFieldsEnd = pDetailFields + m_aDetailFields.getLength();
278         for ( ; pDetailFields < pDetailFieldsEnd; ++pDetailFields, ++pMasterFields )
279         {
280             if ( !pMasterFields->getLength() || !pDetailFields->getLength() )
281                 continue;
282 
283             // if not even the master part of the relationship exists in the parent , the
284             // link is invalid as a whole
285             // #i63674# / 2006-03-28 / frank.schoenheit@sun.com
286             if ( !_rxParentColumns->hasByName( *pMasterFields ) )
287             {
288                 bNeedExchangeLinks = true;
289                 continue;
290             }
291 
292             bool bValidLink = true;
293 
294             // is there an inner parameter with this name? That is, a parameter which is already part of
295             // the very original statement (not the one we create ourselve, with the additional parameters)
296             ParameterInformation::iterator aPos = m_aParameterInformation.find( *pDetailFields );
297             if ( aPos != m_aParameterInformation.end() )
298             {   // there is an inner parameter with this name
299                 aPos->second.eType = eLinkedByParamName;
300                 aStrippedDetailFields.push_back( *pDetailFields );
301             }
302             else
303             {
304                 // does the detail name denote a column?
305                 if ( _rxColumns->hasByName( *pDetailFields ) )
306                 {
307                     ::rtl::OUString sNewParamName;
308                     const ::rtl::OUString sFilterCondition = createFilterConditionFromColumnLink( *pMasterFields, *pDetailFields, sNewParamName );
309                     OSL_PRECOND( sNewParamName.getLength(), "ParameterManager::classifyLinks: createFilterConditionFromColumnLink returned nonsense!" );
310 
311                     // remember meta information about this new parameter
312                     ::std::pair< ParameterInformation::iterator, bool > aInsertionPos =
313                         m_aParameterInformation.insert(
314                             ParameterInformation::value_type( sNewParamName, ParameterMetaData( NULL ) )
315                         );
316                     OSL_ENSURE( aInsertionPos.second, "ParameterManager::classifyLinks: there already was a parameter with this name!" );
317                     aInsertionPos.first->second.eType = eLinkedByColumnName;
318 
319                     // remember the filter component
320                     _out_rAdditionalFilterComponents.push_back( sFilterCondition );
321 
322                     // remember the new "detail field" for this link
323                     aStrippedDetailFields.push_back( sNewParamName );
324                     bNeedExchangeLinks = true;
325                 }
326                 else
327                 {
328                     // the detail field neither denotes a column name, nor a parameter name
329                     bValidLink = false;
330                     bNeedExchangeLinks = true;
331                 }
332             }
333 
334             if ( bValidLink )
335                 aStrippedMasterFields.push_back( *pMasterFields );
336         }
337         OSL_POSTCOND( aStrippedMasterFields.size() == aStrippedDetailFields.size(),
338             "ParameterManager::classifyLinks: inconsistency in new link pairs!" );
339 
340         if ( bNeedExchangeLinks )
341         {
342             ::rtl::OUString *pFields = aStrippedMasterFields.empty() ? 0 : &aStrippedMasterFields[0];
343             m_aMasterFields = Sequence< ::rtl::OUString >( pFields, aStrippedMasterFields.size() );
344             pFields = aStrippedDetailFields.empty() ? 0 : &aStrippedDetailFields[0];
345             m_aDetailFields = Sequence< ::rtl::OUString >( pFields, aStrippedDetailFields.size() );
346         }
347     }
348 
349     //--------------------------------------------------------------------
350     void ParameterManager::analyzeFieldLinks( FilterManager& _rFilterManager, bool& /* [out] */ _rColumnsInLinkDetails )
351     {
352         OSL_PRECOND( isAlive(), "ParameterManager::analyzeFieldLinks: not initialized, or already disposed!" );
353         if ( !isAlive() )
354             return;
355 
356         _rColumnsInLinkDetails = false;
357         try
358         {
359             // the links as determined by the  properties
360             Reference< XPropertySet > xProp = m_xComponent;
361             OSL_ENSURE(xProp.is(),"Some already released my component!");
362             if ( xProp.is() )
363             {
364                 xProp->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_MASTERFIELDS) ) >>= m_aMasterFields;
365                 xProp->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DETAILFIELDS) ) >>= m_aDetailFields;
366             }
367 
368             {
369                 // normalize to equal length
370                 sal_Int32 nMasterLength = m_aMasterFields.getLength();
371                 sal_Int32 nDetailLength = m_aDetailFields.getLength();
372 
373                 if ( nMasterLength > nDetailLength )
374                     m_aMasterFields.realloc( nDetailLength );
375                 else if ( nDetailLength > nMasterLength )
376                     m_aDetailFields.realloc( nMasterLength );
377             }
378 
379             Reference< XNameAccess > xColumns;
380             if ( !getColumns( xColumns, true ) )
381                 // already asserted in getColumns
382                 return;
383 
384             Reference< XNameAccess > xParentColumns;
385             if ( !getParentColumns( xParentColumns, true ) )
386                 return;
387 
388             // classify the links - depending on what the detail fields in each link pair denotes
389             ::std::vector< ::rtl::OUString > aAdditionalFilterComponents;
390             classifyLinks( xParentColumns, xColumns, aAdditionalFilterComponents );
391 
392             // did we find links where the detail field refers to a detail column (instead of a parameter name)?
393             if ( !aAdditionalFilterComponents.empty() )
394             {
395                 const static ::rtl::OUString s_sAnd( RTL_CONSTASCII_USTRINGPARAM( " AND " ) );
396                 // build a conjunction of all the filter components
397                 ::rtl::OUStringBuffer sAdditionalFilter;
398                 for (   ::std::vector< ::rtl::OUString >::const_iterator aComponent = aAdditionalFilterComponents.begin();
399                         aComponent != aAdditionalFilterComponents.end();
400                         ++aComponent
401                     )
402                 {
403                     if ( sAdditionalFilter.getLength() )
404                         sAdditionalFilter.append(s_sAnd);
405 
406                     sAdditionalFilter.appendAscii("( ",((sal_Int32)(sizeof("( ")-1)));
407                     sAdditionalFilter.append(*aComponent);
408                     sAdditionalFilter.appendAscii(" )",((sal_Int32)(sizeof(" )")-1)));
409                 }
410 
411                 // now set this filter at the 's filter manager
412                 _rFilterManager.setFilterComponent( FilterManager::fcLinkFilter, sAdditionalFilter.makeStringAndClear() );
413 
414                 _rColumnsInLinkDetails = true;
415             }
416         }
417         catch( const Exception& )
418         {
419         	OSL_ENSURE( sal_False, "ParameterManager::analyzeFieldLinks: caught an exception!" );
420         }
421     }
422 
423     //--------------------------------------------------------------------
424     void ParameterManager::createOuterParameters()
425     {
426         OSL_PRECOND( !m_pOuterParameters.is(), "ParameterManager::createOuterParameters: outer parameters not initialized!" );
427         OSL_PRECOND( m_xInnerParamUpdate.is(), "ParameterManager::createOuterParameters: no write access to the inner parameters!" );
428         if ( !m_xInnerParamUpdate.is() )
429             return;
430 
431         m_pOuterParameters = new param::ParameterWrapperContainer;
432 
433 #if OSL_DEBUG_LEVEL > 0
434         sal_Int32 nSmallestIndexLinkedByColumnName = -1;
435         sal_Int32 nLargestIndexNotLinkedByColumnName = -1;
436 #endif
437         ::rtl::OUString sName;
438         for ( ParameterInformation::iterator aParam = m_aParameterInformation.begin();
439               aParam != m_aParameterInformation.end();
440               ++aParam
441             )
442         {
443 #if OSL_DEBUG_LEVEL > 0
444             if ( aParam->second.aInnerIndexes.size() )
445                 if ( aParam->second.eType == eLinkedByColumnName )
446                 {
447                     if ( nSmallestIndexLinkedByColumnName == -1 )
448                         nSmallestIndexLinkedByColumnName = aParam->second.aInnerIndexes[ 0 ];
449                 }
450                 else
451                 {
452                     nLargestIndexNotLinkedByColumnName = aParam->second.aInnerIndexes[ aParam->second.aInnerIndexes.size() - 1 ];
453                 }
454 #endif
455             if ( aParam->second.eType != eFilledExternally )
456                 continue;
457 
458             // check which of the parameters have already been visited (e.g. filled via XParameters)
459             size_t nAlreadyVisited = 0;
460             for (   ::std::vector< sal_Int32 >::iterator aIndex = aParam->second.aInnerIndexes.begin();
461                     aIndex != aParam->second.aInnerIndexes.end();
462                     ++aIndex
463                 )
464             {
465                 if ( ( m_aParametersVisited.size() > (size_t)*aIndex ) && m_aParametersVisited[ *aIndex ] )
466                 {   // exclude this index
467                     *aIndex = -1;
468                     ++nAlreadyVisited;
469                 }
470             }
471             if ( nAlreadyVisited == aParam->second.aInnerIndexes.size() )
472                 continue;
473 
474             // need a wrapper for this .... the "inner parameters" as supplied by a result set don't have a "Value"
475             // property, but the parameter listeners expect such a property. So we need an object "aggregating"
476             // xParam and supplying an additional property ("Value")
477             // (it's no real aggregation of course ...)
478             m_pOuterParameters->push_back( new param::ParameterWrapper( aParam->second.xComposerColumn, m_xInnerParamUpdate, aParam->second.aInnerIndexes ) );
479         }
480 
481 #if OSL_DEBUG_LEVEL > 0
482         OSL_ENSURE( ( nSmallestIndexLinkedByColumnName == -1 ) || ( nLargestIndexNotLinkedByColumnName == -1 ) ||
483             ( nSmallestIndexLinkedByColumnName > nLargestIndexNotLinkedByColumnName ),
484             "ParameterManager::createOuterParameters: inconsistency!" );
485 
486         // for the master-detail links, where the detail field denoted a column name, we created an addtional ("artificial")
487         // filter, and *appended* it to all other (potentially) existing filters of the row set. This means that the indexes
488         // for the parameters resulting from the artifical filter should be larger than any other parameter index, and this
489         // is what the assertion checks.
490         // If the assertion fails, then we would need another handling for the "parameters visited" flags, since they're based
491         // on parameter indexes *without* the artificial filter (because this filter is not visible from the outside).
492 #endif
493     }
494 
495     //--------------------------------------------------------------------
496     void ParameterManager::updateParameterInfo( FilterManager& _rFilterManager )
497     {
498         OSL_PRECOND( isAlive(), "ParameterManager::updateParameterInfo: not initialized, or already disposed!" );
499         if ( !isAlive() )
500             return;
501 
502         clearAllParameterInformation();
503         cacheConnectionInfo();
504 
505         // check whether the  is based on a statement/query which requires parameters
506         Reference< XPropertySet > xProp = m_xComponent;
507         OSL_ENSURE(xProp.is(),"Some already released my component!");
508         if ( xProp.is() )
509         {
510             if ( !initializeComposerByComponent( xProp ) )
511             {   // okay, nothing to do
512                 m_bUpToDate = true;
513                 return;
514             } // if ( !initializeComposerByComponent( m_xComponent ) )
515         }
516         OSL_POSTCOND( m_xInnerParamColumns.is(), "ParameterManager::updateParameterInfo: initializeComposerByComponent did nonsense (1)!" );
517 
518         // collect all parameters which are defined by the "inner parameters"
519         collectInnerParameters( false );
520 
521         // analyze the master-detail relationships
522         bool bColumnsInLinkDetails = false;
523         analyzeFieldLinks( _rFilterManager, bColumnsInLinkDetails );
524 
525         if ( bColumnsInLinkDetails )
526         {
527             // okay, in this case, analyzeFieldLinks modified the "real" filter at the RowSet, to contain
528             // an additional restriction (which we created ourself)
529             // So we need to update all information about our inner parameter columns
530             Reference< XPropertySet > xDirectRowSetProps;
531             m_xAggregatedRowSet->queryAggregation( ::getCppuType( &xDirectRowSetProps ) ) >>= xDirectRowSetProps;
532             OSL_VERIFY( initializeComposerByComponent( xDirectRowSetProps ) );
533             collectInnerParameters( true );
534         }
535 
536         if ( !m_nInnerCount )
537         {   // no parameters at all
538             m_bUpToDate = true;
539             return;
540         }
541 
542         // for what now remains as outer parameters, create the wrappers for the single
543         // parameter columns
544         createOuterParameters();
545 
546         m_bUpToDate = true;
547     }
548 
549     //--------------------------------------------------------------------
550     void ParameterManager::fillLinkedParameters( const Reference< XNameAccess >& _rxParentColumns )
551     {
552         OSL_PRECOND( isAlive(), "ParameterManager::fillLinkedParameters: not initialized, or already disposed!" );
553         if ( !isAlive() )
554             return;
555         OSL_PRECOND( m_xInnerParamColumns.is(), "ParameterManager::fillLinkedParameters: no inner parameters found!"                 );
556         OSL_ENSURE ( _rxParentColumns.is(),     "ParameterManager::fillLinkedParameters: invalid parent columns!"                    );
557 
558         try
559         {
560             // the master and detail field( name)s of the
561             const ::rtl::OUString* pMasterFields = m_aMasterFields.getConstArray();
562             const ::rtl::OUString* pDetailFields = m_aDetailFields.getConstArray();
563 
564             sal_Int32 nMasterLen = m_aMasterFields.getLength();
565 			Any aParamType, aScale, aValue;
566 
567             // loop through all master fields. For each of them, get the respective column from the
568             // parent , and forward it's current value as paramter value to the (inner) row set
569             for ( sal_Int32 i = 0; i < nMasterLen; ++i, ++pMasterFields, ++pDetailFields )
570 			{
571                 // does the name denote a valid column in the parent?
572                 if ( !_rxParentColumns->hasByName( *pMasterFields ) )
573                 {
574                     OSL_ENSURE( sal_False, "ParameterManager::fillLinkedParameters: invalid master names should have been stripped long before!" );
575                     continue;
576                 }
577 
578                 // do we, for this name, know where to place the values?
579                 ParameterInformation::const_iterator aParamInfo = m_aParameterInformation.find( *pDetailFields );
580                 if  (  ( aParamInfo == m_aParameterInformation.end() )
581                     || ( aParamInfo->second.aInnerIndexes.empty() )
582                     )
583                 {
584                     OSL_ENSURE( sal_False, "ParameterManager::fillLinkedParameters: nothing known about this detail field!" );
585                     continue;
586                 }
587 
588                 // the concrete master field
589                 Reference< XPropertySet >  xMasterField(_rxParentColumns->getByName( *pMasterFields ),UNO_QUERY);
590 
591                 // the positions where we have to fill in values for the current parameter name
592                 for ( ::std::vector< sal_Int32 >::const_iterator aPosition = aParamInfo->second.aInnerIndexes.begin();
593                       aPosition != aParamInfo->second.aInnerIndexes.end();
594                       ++aPosition
595                     )
596                 {
597                     // the concrete detail field
598                     Reference< XPropertySet >  xDetailField(m_xInnerParamColumns->getByIndex( *aPosition ),UNO_QUERY);
599                     OSL_ENSURE( xDetailField.is(), "ParameterManager::fillLinkedParameters: invalid detail field!" );
600                     if ( !xDetailField.is() )
601                         continue;
602 
603 					// type and scale of the parameter field
604                     sal_Int32 nParamType = DataType::VARCHAR;
605 					OSL_VERIFY( xDetailField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE) ) >>= nParamType );
606 
607                     sal_Int32 nScale = 0;
608 					if ( xDetailField->getPropertySetInfo()->hasPropertyByName( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE) ) )
609 						OSL_VERIFY( xDetailField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE) ) >>= nScale );
610 
611 					// transfer the param value
612 					try
613 					{
614 						m_xInnerParamUpdate->setObjectWithInfo(
615                             *aPosition + 1,                     // parameters are based at 1
616                             xMasterField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_VALUE) ),
617                             nParamType,
618                             nScale
619                         );
620 					}
621 					catch( const Exception& )
622 					{
623 						OSL_ENSURE( sal_False,
624 								    ::rtl::OString( "ParameterManager::fillLinkedParameters: master-detail parameter number " )
625 								+=	::rtl::OString::valueOf( sal_Int32( *aPosition + 1 ) )
626                                 +=  ::rtl::OString( " could not be filled!" ) );
627 					}
628                 }
629 			}
630         }
631         catch( const Exception& )
632         {
633             DBG_UNHANDLED_EXCEPTION();
634         }
635     }
636 
637     //--------------------------------------------------------------------
638     bool ParameterManager::completeParameters( const Reference< XInteractionHandler >& _rxCompletionHandler, const Reference< XConnection > _rxConnection )
639     {
640         OSL_PRECOND( isAlive(), "ParameterManager::completeParameters: not initialized, or already disposed!" );
641         OSL_ENSURE ( _rxCompletionHandler.is(), "ParameterManager::completeParameters: invalid interaction handler!" );
642 
643 		// two continuations (Ok and Cancel)
644         OInteractionAbort* pAbort = new OInteractionAbort;
645 		OParameterContinuation* pParams = new OParameterContinuation;
646 
647 		// the request
648 		ParametersRequest aRequest;
649 		aRequest.Parameters = m_pOuterParameters.get();
650 		aRequest.Connection = _rxConnection;
651 		OInteractionRequest* pRequest = new OInteractionRequest( makeAny( aRequest ) );
652 		Reference< XInteractionRequest > xRequest( pRequest );
653 
654 		// some knittings
655 		pRequest->addContinuation( pAbort );
656 		pRequest->addContinuation( pParams );
657 
658 		// execute the request
659         try
660         {
661     		_rxCompletionHandler->handle( xRequest );
662         }
663         catch( const Exception& )
664         {
665         	OSL_ENSURE( sal_False, "ParameterManager::completeParameters: caught an exception while calling the handler!" );
666         }
667 
668 		if ( !pParams->wasSelected() )
669 			// canceled by the user (i.e. (s)he canceled the dialog)
670 			return false;
671 
672         try
673         {
674 		    // transfer the values from the continuation object to the parameter columns
675 		    Sequence< PropertyValue > aFinalValues = pParams->getValues();
676 		    const PropertyValue* pFinalValues = aFinalValues.getConstArray();
677 		    for ( sal_Int32 i = 0; i < aFinalValues.getLength(); ++i, ++pFinalValues )
678 		    {
679                 Reference< XPropertySet > xParamColumn(aRequest.Parameters->getByIndex( i ),UNO_QUERY);
680 			    if ( xParamColumn.is() )
681 			    {
682             #ifdef DBG_UTIL
683 				    ::rtl::OUString sName;
684 				    xParamColumn->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME) ) >>= sName;
685 				    OSL_ENSURE( sName == pFinalValues->Name, "ParameterManager::completeParameters: inconsistent parameter names!" );
686             #endif
687 				    xParamColumn->setPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_VALUE), pFinalValues->Value );
688 					    // the property sets are wrapper classes, translating the Value property into a call to
689 					    // the appropriate XParameters interface
690 			    }
691 		    }
692         }
693         catch( const Exception& )
694         {
695         	OSL_ENSURE( sal_False, "ParameterManager::completeParameters: caught an exception while propagating the values!" );
696         }
697         return true;
698     }
699 
700     //--------------------------------------------------------------------
701     bool ParameterManager::consultParameterListeners( ::osl::ResettableMutexGuard& _rClearForNotifies )
702     {
703 	    bool bCanceled = false;
704 
705         sal_Int32 nParamsLeft = m_pOuterParameters->getParameters().size();
706             // TODO: shouldn't we subtract all the parameters which were already visited?
707 		if ( nParamsLeft )
708 		{
709 			::cppu::OInterfaceIteratorHelper aIter( m_aParameterListeners );
710             Reference< XPropertySet > xProp = m_xComponent;
711             OSL_ENSURE(xProp.is(),"Some already released my component!");
712 			DatabaseParameterEvent aEvent( xProp.get(), m_pOuterParameters.get() );
713 
714             _rClearForNotifies.clear();
715 			while ( aIter.hasMoreElements() && !bCanceled )
716 				bCanceled = !static_cast< XDatabaseParameterListener* >( aIter.next() )->approveParameter( aEvent );
717 			_rClearForNotifies.reset();
718 		}
719 
720         return !bCanceled;
721     }
722 
723     //--------------------------------------------------------------------
724     bool ParameterManager::fillParameterValues( const Reference< XInteractionHandler >& _rxCompletionHandler, ::osl::ResettableMutexGuard& _rClearForNotifies )
725     {
726         OSL_PRECOND( isAlive(), "ParameterManager::fillParameterValues: not initialized, or already disposed!" );
727         if ( !isAlive() )
728             return true;
729 
730         if ( m_nInnerCount == 0 )
731             // no parameters at all
732 		    return true;
733 
734         // fill the parameters from the master-detail relationship
735         Reference< XNameAccess > xParentColumns;
736         if ( getParentColumns( xParentColumns, false ) && xParentColumns->hasElements() && m_aMasterFields.getLength() )
737             fillLinkedParameters( xParentColumns );
738 
739         // let the user (via the interaction handler) fill all remaining parameters
740         Reference< XConnection > xConnection;
741         getConnection( xConnection );
742 
743         if ( _rxCompletionHandler.is() )
744             return completeParameters( _rxCompletionHandler, xConnection );
745 
746         return consultParameterListeners( _rClearForNotifies );
747     }
748 
749     //--------------------------------------------------------------------
750     bool ParameterManager::getConnection( Reference< XConnection >& /* [out] */ _rxConnection )
751     {
752         OSL_PRECOND( isAlive(), "ParameterManager::getConnection: not initialized, or already disposed!" );
753         if ( !isAlive() )
754             return false;
755 
756         _rxConnection.clear();
757         try
758         {
759             Reference< XPropertySet > xProp = m_xComponent;
760             OSL_ENSURE(xProp.is(),"Some already released my component!");
761             if ( xProp.is() )
762                 xProp->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ACTIVE_CONNECTION) ) >>= _rxConnection;
763         }
764         catch( const Exception& )
765         {
766         	OSL_ENSURE( sal_False, "ParameterManager::getConnection: could not retrieve the connection of the !" );
767         }
768         return _rxConnection.is();
769     }
770 
771     //--------------------------------------------------------------------
772     void ParameterManager::cacheConnectionInfo() SAL_THROW(( ))
773     {
774         try
775         {
776             Reference< XConnection > xConnection;
777             getConnection( xConnection );
778             Reference< XDatabaseMetaData > xMeta;
779             if ( xConnection.is() )
780                 xMeta = xConnection->getMetaData();
781             if ( xMeta.is() )
782             {
783                 m_sIdentifierQuoteString = xMeta->getIdentifierQuoteString();
784                 m_sSpecialCharacters = xMeta->getExtraNameCharacters();
785             }
786         }
787         catch( const Exception& )
788         {
789         	OSL_ENSURE( sal_False, "ParameterManager::cacheConnectionInfo: caught an exception!" );
790         }
791     }
792 
793     //--------------------------------------------------------------------
794     bool ParameterManager::getColumns( Reference< XNameAccess >& /* [out] */ _rxColumns, bool _bFromComposer ) SAL_THROW(( Exception ))
795     {
796         _rxColumns.clear();
797 
798         Reference< XColumnsSupplier > xColumnSupp;
799         if ( _bFromComposer )
800             xColumnSupp = xColumnSupp.query( m_xComposer );
801         else
802             xColumnSupp.set( m_xComponent.get(),UNO_QUERY);
803         if ( xColumnSupp.is() )
804             _rxColumns = xColumnSupp->getColumns();
805         OSL_ENSURE( _rxColumns.is(), "ParameterManager::getColumns: could not retrieve the columns for the detail !" );
806 
807         return _rxColumns.is();
808     }
809 
810     //--------------------------------------------------------------------
811     bool ParameterManager::getParentColumns( Reference< XNameAccess >& /* [out] */ _out_rxParentColumns, bool _bFromComposer )
812     {
813         OSL_PRECOND( isAlive(), "ParameterManager::getParentColumns: not initialized, or already disposed!" );
814 
815         _out_rxParentColumns.clear();
816         try
817         {
818             // get the parent of the component we're working for
819             Reference< XChild > xAsChild( m_xComponent.get(), UNO_QUERY_THROW );
820             Reference< XPropertySet > xParent( xAsChild->getParent(), UNO_QUERY );
821             if ( !xParent.is() )
822                 return false;
823 
824             // the columns supplier: either from a composer, or directly from the
825             Reference< XColumnsSupplier > xParentColSupp;
826             if ( _bFromComposer )
827             {
828                 // re-create the parent composer all the time. Else, we'd have to bother with
829                 // being a listener at its properties, its loaded state, and event the parent-relationship.
830                 m_xParentComposer.reset(
831                     getCurrentSettingsComposer( xParent, m_xORB ),
832                     SharedQueryComposer::TakeOwnership
833                 );
834                 xParentColSupp = xParentColSupp.query( m_xParentComposer );
835             }
836             else
837                 xParentColSupp = xParentColSupp.query( xParent );
838 
839             // get the columns of the parent
840             if ( xParentColSupp.is() )
841                 _out_rxParentColumns = xParentColSupp->getColumns();
842         }
843         catch( const Exception& )
844         {
845         	OSL_ENSURE( sal_False, "ParameterManager::getParentColumns: caught an exception!" );
846         }
847         return _out_rxParentColumns.is();
848     }
849 
850     //--------------------------------------------------------------------
851     void ParameterManager::addParameterListener( const Reference< XDatabaseParameterListener >& _rxListener )
852     {
853         if ( _rxListener.is() )
854             m_aParameterListeners.addInterface( _rxListener );
855     }
856 
857     //--------------------------------------------------------------------
858     void ParameterManager::removeParameterListener( const Reference< XDatabaseParameterListener >& _rxListener )
859     {
860         m_aParameterListeners.removeInterface( _rxListener );
861     }
862 
863     //--------------------------------------------------------------------
864     void ParameterManager::resetParameterValues( ) SAL_THROW(())
865     {
866         OSL_PRECOND( isAlive(), "ParameterManager::resetParameterValues: not initialized, or already disposed!" );
867         if ( !isAlive() )
868             return;
869 
870         if ( !m_nInnerCount )
871             // no parameters at all
872             return;
873 
874         try
875         {
876             Reference< XNameAccess > xColumns;
877             if ( !getColumns( xColumns, false ) )
878                 // already asserted in getColumns
879                 return;
880 
881 		    Reference< XNameAccess > xParentColumns;
882             if ( !getParentColumns( xParentColumns, false ) )
883                 return;
884 
885             // loop through all links pairs
886 		    const ::rtl::OUString* pMasterFields = m_aMasterFields.getConstArray();
887 		    const ::rtl::OUString* pDetailFields = m_aDetailFields.getConstArray();
888 
889             Reference< XPropertySet > xMasterField;
890             Reference< XPropertySet > xDetailField;
891 
892             // now really ....
893 		    const ::rtl::OUString* pDetailFieldsEnd = pDetailFields + m_aDetailFields.getLength();
894 		    for ( ; pDetailFields < pDetailFieldsEnd; ++pDetailFields, ++pMasterFields )
895 		    {
896                 if ( !xParentColumns->hasByName( *pMasterFields ) )
897                 {
898                     // if this name is unknown in the parent columns, then we don't have a source
899                     // for copying the value to the detail columns
900                     OSL_ENSURE( sal_False, "ParameterManager::resetParameterValues: this should have been stripped long before!" );
901                     continue;
902                 }
903 
904                 // for all inner parameters which are bound to the name as specified by the
905                 // slave element of the link, propagate the value from the master column to this
906                 // parameter column
907                 ParameterInformation::const_iterator aParamInfo = m_aParameterInformation.find( *pDetailFields );
908                 if  (  ( aParamInfo == m_aParameterInformation.end() )
909                     || ( aParamInfo->second.aInnerIndexes.empty() )
910                     )
911                 {
912                     OSL_ENSURE( sal_False, "ParameterManager::resetParameterValues: nothing known about this detail field!" );
913                     continue;
914                 }
915 
916                 xParentColumns->getByName( *pMasterFields ) >>= xMasterField;
917                 if ( !xMasterField.is() )
918                     continue;
919 
920                 for ( ::std::vector< sal_Int32 >::const_iterator aPosition = aParamInfo->second.aInnerIndexes.begin();
921                       aPosition != aParamInfo->second.aInnerIndexes.end();
922                       ++aPosition
923                     )
924                 {
925 				    Reference< XPropertySet > xInnerParameter;
926 					m_xInnerParamColumns->getByIndex( *aPosition ) >>= xInnerParameter;
927                     if ( !xInnerParameter.is() )
928                         continue;
929 
930                     ::rtl::OUString sParamColumnRealName;
931 					xInnerParameter->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME) ) >>= sParamColumnRealName;
932 					if ( xColumns->hasByName( sParamColumnRealName ) )
933 					{	// our own columns have a column which's name equals the real name of the param column
934 						// -> transfer the value property
935 						xColumns->getByName( sParamColumnRealName ) >>= xDetailField;
936 						if ( xDetailField.is() )
937 							xDetailField->setPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_VALUE), xMasterField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_VALUE) ) );
938 					}
939                 }
940 		    }
941         }
942         catch( const Exception& )
943         {
944             OSL_ENSURE( sal_False, "ParameterManager::resetParameterValues: caught an exception!" );
945         }
946 
947     }
948 
949     //--------------------------------------------------------------------
950     void ParameterManager::externalParameterVisited( sal_Int32 _nIndex )
951     {
952 		if ( m_aParametersVisited.size() < (size_t)_nIndex )
953 		{
954 			m_aParametersVisited.reserve( _nIndex );
955 			for ( sal_Int32 i = m_aParametersVisited.size(); i < _nIndex; ++i )
956 				m_aParametersVisited.push_back( false );
957 		}
958 		m_aParametersVisited[ _nIndex - 1 ] = true;
959     }
960 
961 #define VISIT_PARAMETER( method ) \
962         ::osl::MutexGuard aGuard( m_rMutex ); \
963         OSL_ENSURE( m_xInnerParamUpdate.is(), "ParameterManager::XParameters::setXXX: no XParameters access to the RowSet!" ); \
964         if ( !m_xInnerParamUpdate.is() ) \
965             return; \
966         m_xInnerParamUpdate->method; \
967         externalParameterVisited( _nIndex ) \
968 
969     //--------------------------------------------------------------------
970     void ParameterManager::setNull( sal_Int32 _nIndex, sal_Int32 sqlType )
971 	{
972         VISIT_PARAMETER( setNull( _nIndex, sqlType ) );
973 	}
974 
975     //--------------------------------------------------------------------
976     void ParameterManager::setObjectNull( sal_Int32 _nIndex, sal_Int32 sqlType, const ::rtl::OUString& typeName )
977 	{
978         VISIT_PARAMETER( setObjectNull( _nIndex, sqlType, typeName ) );
979 	}
980 
981     //--------------------------------------------------------------------
982     void ParameterManager::setBoolean( sal_Int32 _nIndex, sal_Bool x )
983 	{
984         VISIT_PARAMETER( setBoolean( _nIndex, x ) );
985 	}
986 
987     //--------------------------------------------------------------------
988     void ParameterManager::setByte( sal_Int32 _nIndex, sal_Int8 x )
989 	{
990         VISIT_PARAMETER( setByte( _nIndex, x ) );
991 	}
992 
993     //--------------------------------------------------------------------
994     void ParameterManager::setShort( sal_Int32 _nIndex, sal_Int16 x )
995 	{
996         VISIT_PARAMETER( setShort( _nIndex, x ) );
997 	}
998 
999     //--------------------------------------------------------------------
1000     void ParameterManager::setInt( sal_Int32 _nIndex, sal_Int32 x )
1001 	{
1002         VISIT_PARAMETER( setInt( _nIndex, x ) );
1003 	}
1004 
1005     //--------------------------------------------------------------------
1006     void ParameterManager::setLong( sal_Int32 _nIndex, sal_Int64 x )
1007 	{
1008         VISIT_PARAMETER( setLong( _nIndex, x ) );
1009 	}
1010 
1011     //--------------------------------------------------------------------
1012     void ParameterManager::setFloat( sal_Int32 _nIndex, float x )
1013 	{
1014         VISIT_PARAMETER( setFloat( _nIndex, x ) );
1015 	}
1016 
1017     //--------------------------------------------------------------------
1018     void ParameterManager::setDouble( sal_Int32 _nIndex, double x )
1019 	{
1020         VISIT_PARAMETER( setDouble( _nIndex, x ) );
1021 	}
1022 
1023     //--------------------------------------------------------------------
1024     void ParameterManager::setString( sal_Int32 _nIndex, const ::rtl::OUString& x )
1025 	{
1026         VISIT_PARAMETER( setString( _nIndex, x ) );
1027 	}
1028 
1029     //--------------------------------------------------------------------
1030     void ParameterManager::setBytes( sal_Int32 _nIndex, const ::com::sun::star::uno::Sequence< sal_Int8 >& x )
1031 	{
1032         VISIT_PARAMETER( setBytes( _nIndex, x ) );
1033 	}
1034 
1035     //--------------------------------------------------------------------
1036     void ParameterManager::setDate( sal_Int32 _nIndex, const ::com::sun::star::util::Date& x )
1037 	{
1038         VISIT_PARAMETER( setDate( _nIndex, x ) );
1039 	}
1040 
1041     //--------------------------------------------------------------------
1042     void ParameterManager::setTime( sal_Int32 _nIndex, const ::com::sun::star::util::Time& x )
1043 	{
1044         VISIT_PARAMETER( setTime( _nIndex, x ) );
1045 	}
1046 
1047     //--------------------------------------------------------------------
1048     void ParameterManager::setTimestamp( sal_Int32 _nIndex, const ::com::sun::star::util::DateTime& x )
1049 	{
1050         VISIT_PARAMETER( setTimestamp( _nIndex, x ) );
1051 	}
1052 
1053     //--------------------------------------------------------------------
1054     void ParameterManager::setBinaryStream( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, sal_Int32 length )
1055 	{
1056         VISIT_PARAMETER( setBinaryStream( _nIndex, x, length ) );
1057 	}
1058 
1059     //--------------------------------------------------------------------
1060     void ParameterManager::setCharacterStream( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream>& x, sal_Int32 length )
1061 	{
1062         VISIT_PARAMETER( setCharacterStream( _nIndex, x, length ) );
1063 	}
1064 
1065     //--------------------------------------------------------------------
1066     void ParameterManager::setObject( sal_Int32 _nIndex, const ::com::sun::star::uno::Any& x )
1067 	{
1068         VISIT_PARAMETER( setObject( _nIndex, x ) );
1069 	}
1070 
1071     //--------------------------------------------------------------------
1072     void ParameterManager::setObjectWithInfo( sal_Int32 _nIndex, const ::com::sun::star::uno::Any& x, sal_Int32 targetSqlType, sal_Int32 scale )
1073 	{
1074         VISIT_PARAMETER( setObjectWithInfo( _nIndex, x, targetSqlType, scale ) );
1075 	}
1076 
1077     //--------------------------------------------------------------------
1078     void ParameterManager::setRef( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRef>& x )
1079 	{
1080         VISIT_PARAMETER( setRef( _nIndex, x ) );
1081 	}
1082 
1083     //--------------------------------------------------------------------
1084     void ParameterManager::setBlob( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XBlob>& x )
1085 	{
1086         VISIT_PARAMETER( setBlob( _nIndex, x ) );
1087 	}
1088 
1089     //--------------------------------------------------------------------
1090     void ParameterManager::setClob( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XClob>& x )
1091 	{
1092         VISIT_PARAMETER( setClob( _nIndex, x ) );
1093 	}
1094 
1095     //--------------------------------------------------------------------
1096     void ParameterManager::setArray( sal_Int32 _nIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XArray>& x )
1097 	{
1098         VISIT_PARAMETER( setArray( _nIndex, x ) );
1099 	}
1100 
1101     //--------------------------------------------------------------------
1102     void ParameterManager::clearParameters( )
1103 	{
1104         if ( m_xInnerParamUpdate.is() )
1105             m_xInnerParamUpdate->clearParameters( );
1106     }
1107 
1108     //====================================================================
1109     //= OParameterContinuation
1110     //====================================================================
1111     //--------------------------------------------------------------------
1112     void SAL_CALL OParameterContinuation::setParameters( const Sequence< PropertyValue >& _rValues ) throw( RuntimeException )
1113     {
1114 	    m_aValues = _rValues;
1115     }
1116 
1117 //........................................................................
1118 }   // namespace frm
1119 //........................................................................
1120 
1121