1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 // MARKER(update_precomp.py): autogen include statement, do not remove
24 #include "precompiled_dbui.hxx"
25 
26 #include "dbu_reghelper.hxx"
27 #include "dbu_resource.hrc"
28 #include "dbu_uno.hrc"
29 #include "dbustrings.hrc"
30 #include "moduledbu.hxx"
31 #include "sqlmessage.hxx"
32 #include "WCopyTable.hxx"
33 
34 /** === begin UNO includes === **/
35 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
36 #include <com/sun/star/sdb/application/XCopyTableWizard.hpp>
37 #include <com/sun/star/sdb/application/CopyTableContinuation.hpp>
38 #include <com/sun/star/sdb/application/CopyTableOperation.hpp>
39 #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
40 #include <com/sun/star/lang/NotInitializedException.hpp>
41 #include <com/sun/star/sdbc/XDataSource.hpp>
42 #include <com/sun/star/sdbc/DataType.hpp>
43 #include <com/sun/star/container/XNameAccess.hpp>
44 #include <com/sun/star/container/XChild.hpp>
45 #include <com/sun/star/task/XInteractionHandler.hpp>
46 #include <com/sun/star/frame/XModel.hpp>
47 #include <com/sun/star/sdb/XDocumentDataSource.hpp>
48 #include <com/sun/star/sdb/XCompletedConnection.hpp>
49 #include <com/sun/star/sdb/CommandType.hpp>
50 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
51 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
52 #include <com/sun/star/lang/DisposedException.hpp>
53 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
54 #include <com/sun/star/sdbc/XParameters.hpp>
55 #include <com/sun/star/sdbc/XRow.hpp>
56 #include <com/sun/star/sdbc/XBlob.hpp>
57 #include <com/sun/star/sdbc/XClob.hpp>
58 #include <com/sun/star/sdbcx/XRowLocate.hpp>
59 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
60 #include <com/sun/star/sdb/SQLContext.hpp>
61 #include <com/sun/star/sdbc/XDriverManager.hpp>
62 /** === end UNO includes === **/
63 
64 #include <comphelper/componentcontext.hxx>
65 #include <comphelper/interaction.hxx>
66 #include <comphelper/namedvaluecollection.hxx>
67 #include <comphelper/proparrhlp.hxx>
68 #include <comphelper/string.hxx>
69 #include <connectivity/dbexception.hxx>
70 #include <connectivity/dbtools.hxx>
71 #include <cppuhelper/exc_hlp.hxx>
72 #include <cppuhelper/implbase1.hxx>
73 #include <rtl/ustrbuf.hxx>
74 #include <rtl/logfile.hxx>
75 #include <svtools/genericunodialog.hxx>
76 #include <tools/diagnose_ex.h>
77 #include <unotools/sharedunocomponent.hxx>
78 #include <vcl/msgbox.hxx>
79 #include <vcl/waitobj.hxx>
80 
81 //........................................................................
82 namespace dbaui
83 {
84 //........................................................................
85 
86 	/** === begin UNO using === **/
87 	using ::com::sun::star::uno::Reference;
88 	using ::com::sun::star::uno::XInterface;
89 	using ::com::sun::star::uno::UNO_QUERY;
90 	using ::com::sun::star::uno::UNO_QUERY_THROW;
91 	using ::com::sun::star::uno::UNO_SET_THROW;
92 	using ::com::sun::star::uno::Exception;
93 	using ::com::sun::star::uno::RuntimeException;
94 	using ::com::sun::star::uno::Any;
95 	using ::com::sun::star::uno::makeAny;
96     using ::com::sun::star::uno::Sequence;
97     using ::com::sun::star::beans::XPropertySetInfo;
98     using ::com::sun::star::lang::XMultiServiceFactory;
99     using ::com::sun::star::beans::Property;
100     using ::com::sun::star::sdb::application::XCopyTableWizard;
101     using ::com::sun::star::sdb::application::XCopyTableListener;
102     using ::com::sun::star::sdb::application::CopyTableRowEvent;
103     using ::com::sun::star::beans::Optional;
104     using ::com::sun::star::lang::IllegalArgumentException;
105     using ::com::sun::star::ucb::AlreadyInitializedException;
106     using ::com::sun::star::beans::XPropertySet;
107     using ::com::sun::star::lang::NotInitializedException;
108     using ::com::sun::star::lang::XServiceInfo;
109     using ::com::sun::star::sdbc::XConnection;
110     using ::com::sun::star::sdbc::XDataSource;
111     using ::com::sun::star::container::XNameAccess;
112     using ::com::sun::star::container::XChild;
113     using ::com::sun::star::task::XInteractionHandler;
114     using ::com::sun::star::frame::XModel;
115     using ::com::sun::star::sdb::XDocumentDataSource;
116     using ::com::sun::star::sdb::XCompletedConnection;
117     using ::com::sun::star::lang::WrappedTargetException;
118     using ::com::sun::star::sdbcx::XTablesSupplier;
119     using ::com::sun::star::sdb::XQueriesSupplier;
120     using ::com::sun::star::lang::DisposedException;
121     using ::com::sun::star::sdbc::XPreparedStatement;
122     using ::com::sun::star::sdb::XSingleSelectQueryComposer;
123     using ::com::sun::star::sdbc::XDatabaseMetaData;
124     using ::com::sun::star::sdbcx::XColumnsSupplier;
125     using ::com::sun::star::sdbc::XParameters;
126     using ::com::sun::star::sdbc::XResultSet;
127     using ::com::sun::star::sdbc::XRow;
128 	using ::com::sun::star::sdbc::XBlob;
129 	using ::com::sun::star::sdbc::XClob;
130     using ::com::sun::star::sdbcx::XRowLocate;
131     using ::com::sun::star::sdbc::XResultSetMetaDataSupplier;
132     using ::com::sun::star::sdbc::XResultSetMetaData;
133     using ::com::sun::star::sdbc::SQLException;
134     using ::com::sun::star::sdb::SQLContext;
135     using ::com::sun::star::sdbc::XDriverManager;
136     using ::com::sun::star::beans::PropertyValue;
137 	/** === end UNO using === **/
138     namespace CopyTableOperation = ::com::sun::star::sdb::application::CopyTableOperation;
139     namespace CopyTableContinuation = ::com::sun::star::sdb::application::CopyTableContinuation;
140     namespace CommandType = ::com::sun::star::sdb::CommandType;
141     namespace DataType = ::com::sun::star::sdbc::DataType;
142 
143     typedef ::utl::SharedUNOComponent< XConnection >    SharedConnection;
144     typedef Reference< XInteractionHandler >            InteractionHandler;
145 
146     //=========================================================================
147     //= CopyTableWizard
148     //=========================================================================
149     typedef ::svt::OGenericUnoDialog        CopyTableWizard_DialogBase;
150     typedef ::cppu::ImplInheritanceHelper1  <   CopyTableWizard_DialogBase
151                                             ,   XCopyTableWizard
152                                             >   CopyTableWizard_Base;
153     class CopyTableWizard
154             :public CopyTableWizard_Base
155 		    ,public ::comphelper::OPropertyArrayUsageHelper< CopyTableWizard >
156     {
157     public:
158 	    // XServiceInfo
159 	    virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException);
160 	    virtual ::comphelper::StringSequence SAL_CALL getSupportedServiceNames() throw(RuntimeException);
161 
162 	    // XServiceInfo - static methods
163 	    static Sequence< ::rtl::OUString >  getSupportedServiceNames_Static(void) throw( RuntimeException );
164 	    static ::rtl::OUString              getImplementationName_Static(void) throw( RuntimeException );
165 	    static Reference< XInterface >      Create( const Reference< XMultiServiceFactory >& );
166 
167         // XCopyTableWizard
168         virtual ::sal_Int16 SAL_CALL getOperation() throw (RuntimeException);
169         virtual void SAL_CALL setOperation( ::sal_Int16 _operation ) throw (IllegalArgumentException, RuntimeException);
170         virtual ::rtl::OUString SAL_CALL getDestinationTableName() throw (RuntimeException);
171         virtual void SAL_CALL setDestinationTableName( const ::rtl::OUString& _destinationTableName ) throw (RuntimeException);
172         virtual Optional< ::rtl::OUString > SAL_CALL getCreatePrimaryKey() throw (RuntimeException);
173         virtual void SAL_CALL setCreatePrimaryKey( const Optional< ::rtl::OUString >& _newPrimaryKey ) throw (IllegalArgumentException, RuntimeException);
174         virtual sal_Bool SAL_CALL getUseHeaderLineAsColumnNames() throw (RuntimeException);
175         virtual void SAL_CALL setUseHeaderLineAsColumnNames( sal_Bool _bUseHeaderLineAsColumnNames ) throw (RuntimeException);
176         virtual void SAL_CALL addCopyTableListener( const Reference< XCopyTableListener >& Listener ) throw (RuntimeException);
177         virtual void SAL_CALL removeCopyTableListener( const Reference< XCopyTableListener >& Listener ) throw (RuntimeException);
178 
179         // XCopyTableWizard::XExecutableDialog
180         virtual void SAL_CALL setTitle( const ::rtl::OUString& aTitle ) throw (RuntimeException);
181         virtual ::sal_Int16 SAL_CALL execute(  ) throw (RuntimeException);
182 
183         // XInitialization
184         virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException);
185 
186 	    // XPropertySet
187 	    virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo() throw(RuntimeException);
188 	    virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
189 
190 	    // OPropertyArrayUsageHelper
191 	    virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
192 
193     public:
getMutex()194         ::osl::Mutex&   getMutex() { return m_aMutex; }
isInitialized() const195         bool            isInitialized() const { return m_xSourceConnection.is() && m_pSourceObject.get() && m_xDestConnection.is(); }
196 
197     protected:
198 	    CopyTableWizard( const Reference< XMultiServiceFactory >& _rxORB );
199         ~CopyTableWizard();
200 
201         // OGenericUnoDialog overridables
202 	    virtual Dialog*	createDialog( Window* _pParent );
203         virtual void executedDialog( sal_Int16 _nExecutionResult );
204 
205     private:
206         /// ensures our current attribute values are reflected in the dialog
207         void    impl_attributesToDialog_nothrow( OCopyTableWizard& _rDialog ) const;
208 
209         /// ensures the current dialog settings are reflected in our attributes
210         void    impl_dialogToAttributes_nothrow( const OCopyTableWizard& _rDialog );
211 
212         /** returns our typed dialog
213 
214             @throws ::com::sun::star::uno::RuntimeException
215                 if we don't have a dialog at the moment the method is called
216         */
217         OCopyTableWizard&
218                 impl_getDialog_throw();
219 
220         /** returns our typed dialog
221 
222             @throws ::com::sun::star::uno::RuntimeException
223                 if we don't have a dialog at the moment the method is called
224         */
225         const OCopyTableWizard&
226                 impl_getDialog_throw() const;
227 
228         /** ensures the given argument sequence contains a valid data access descriptor at the given position
229             @param _rAllArgs
230                 the arguments as passed to ->initialize
231             @param _nArgPos
232                 the position within ->_rAllArgs which contains the data access descriptor
233             @param _out_rxConnection
234                 will, upon successful return, contain the connection for the data source
235             @param _out_rxDocInteractionHandler
236                 will, upon successful return, contain the interaction handler which could
237                 be deduced from database document described by the descriptor, if any.
238                 (It is possible that the descriptor does not allow to deduce a database document,
239                 in which case <code>_out_rxDocInteractionHandler</code> will be <NULL/>.)
240             @return the data access descriptor
241         */
242         Reference< XPropertySet >
243                 impl_ensureDataAccessDescriptor_throw(
244                     const Sequence< Any >& _rAllArgs,
245                     const sal_Int16 _nArgPos,
246                     SharedConnection& _out_rxConnection,
247                     InteractionHandler& _out_rxDocInteractionHandler
248                 ) const;
249 
250         /** extracts the source object (table or query) described by the given descriptor,
251             relative to m_xSourceConnection
252         */
253         ::std::auto_ptr< ICopyTableSourceObject >
254                 impl_extractSourceObject_throw(
255                     const Reference< XPropertySet >& _rxDescriptor,
256                     sal_Int32& _out_rCommandType
257                 ) const;
258 
259         /** extracts the result set to copy records from, and the selection-related aspects, if any.
260 
261             Effectively, this method extracts m_xSourceResultSet, m_aSourceSelection, and m_bSourceSelectionBookmarks.
262 
263             If an inconsistent/insufficent sub set of those properties is present in the descriptor, and exception
264             is thrown.
265         */
266         void    impl_extractSourceResultSet_throw(
267                     const Reference< XPropertySet >& i_rDescriptor
268                 );
269 
270         /** checks whether the given copy source descriptor contains settings which are not
271             supported (yet)
272 
273             Throws an IllegalArgumentException if the descriptor contains a valid setting, which is
274             not yet supported.
275         */
276         void    impl_checkForUnsupportedSettings_throw(
277             const Reference< XPropertySet >& _rxSourceDescriptor ) const;
278 
279         /** obtaines the connection described by the given data access descriptor
280 
281             If needed and possible, the method will ask the user, using the interaction
282             handler associated with the database described by the descriptor.
283 
284             All errors are handled with the InteractionHandler associated with the data source,
285             if there is one. Else, they will be silenced (but asserted in non-product builds).
286 
287             @param _rxDataSourceDescriptor
288                 the data access descriptor describing the data source whose connection
289                 should be obtained. Must not be <NULL/>.
290             @param _out_rxDocInteractionHandler
291                 the interaction handler which could be deduced from the descriptor
292 
293             @throws RuntimeException
294                 if anything goes seriously wrong.
295         */
296         SharedConnection
297                 impl_extractConnection_throw(
298                     const Reference< XPropertySet >& _rxDataSourceDescriptor,
299                     InteractionHandler& _out_rxDocInteractionHandler
300                 ) const;
301 
302         /** actually copies the table
303 
304             This method is called after the dialog has been successfully executed.
305         */
306         void    impl_doCopy_nothrow();
307 
308         /** creates the INSERT INTO statement
309             @param  _xTable The destination table.
310         */
311         ::rtl::OUString impl_getServerSideCopyStatement_throw( const Reference< XPropertySet >& _xTable );
312 
313         /** creates the statement which, when executed, will produce the source data to copy
314 
315             If the source object refers to a query which contains parameters, those parameters
316             are filled in, using an interaction handler.
317         */
318         ::utl::SharedUNOComponent< XPreparedStatement >
319                 impl_createSourceStatement_throw() const;
320 
321         /** copies the data rows from the given source result set to the given destination table
322         */
323         void    impl_copyRows_throw(
324                     const Reference< XResultSet >& _rxSourceResultSet,
325                     const Reference< XPropertySet >& _rxDestTable
326                 );
327 
328         /** processes an error which occurred during copying
329 
330             First, all listeners are ask. If a listener tells to cancel or continue copying, this is reported to the
331             method's caller. If a listener tells to ask the user, this is done, and the user's decision is
332             reported to the method's caller.
333 
334             @return
335                 <TRUE/> if and only if copying should be continued.
336         */
337         bool    impl_processCopyError_nothrow(
338                     const CopyTableRowEvent& _rEvent );
339 
340 private:
341         ::comphelper::ComponentContext  m_aContext;
342 
343         // attributes
344         sal_Int16                       m_nOperation;
345         ::rtl::OUString                 m_sDestinationTable;
346         Optional< ::rtl::OUString >     m_aPrimaryKeyName;
347         sal_Bool                        m_bUseHeaderLineAsColumnNames;
348 
349         // source
350         SharedConnection                m_xSourceConnection;
351         sal_Int32                       m_nCommandType;
352         ::std::auto_ptr< ICopyTableSourceObject >
353                                         m_pSourceObject;
354         Reference< XResultSet >         m_xSourceResultSet;
355         Sequence< Any >                 m_aSourceSelection;
356         sal_Bool                        m_bSourceSelectionBookmarks;
357 
358         // destination
359         SharedConnection                m_xDestConnection;
360 
361         // other
362         InteractionHandler              m_xInteractionHandler;
363         ::cppu::OInterfaceContainerHelper
364                                         m_aCopyTableListeners;
365         sal_Int16                       m_nOverrideExecutionResult;
366     };
367 
368 //=========================================================================
369 //= MethodGuard
370 //=========================================================================
371 class CopyTableAccessGuard
372 {
373 public:
CopyTableAccessGuard(CopyTableWizard & _rWizard)374     CopyTableAccessGuard( CopyTableWizard& _rWizard )
375         :m_rWizard( _rWizard )
376     {
377         m_rWizard.getMutex().acquire();
378         if ( !m_rWizard.isInitialized() )
379             throw NotInitializedException();
380     }
381 
~CopyTableAccessGuard()382     ~CopyTableAccessGuard()
383     {
384         m_rWizard.getMutex().release();
385     }
386 
387 private:
388     CopyTableWizard&    m_rWizard;
389 };
390 
391 //=========================================================================
392 //-------------------------------------------------------------------------
CopyTableWizard(const Reference<XMultiServiceFactory> & _rxORB)393 CopyTableWizard::CopyTableWizard( const Reference< XMultiServiceFactory >& _rxORB )
394     :CopyTableWizard_Base( _rxORB )
395     ,m_aContext( _rxORB )
396     ,m_nOperation( CopyTableOperation::CopyDefinitionAndData )
397     ,m_sDestinationTable()
398     ,m_aPrimaryKeyName( sal_False, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ID" ) ))
399     ,m_bUseHeaderLineAsColumnNames( sal_True )
400     ,m_xSourceConnection()
401     ,m_nCommandType( CommandType::COMMAND )
402     ,m_pSourceObject()
403     ,m_xSourceResultSet()
404     ,m_aSourceSelection()
405     ,m_bSourceSelectionBookmarks( sal_True )
406     ,m_xDestConnection()
407     ,m_aCopyTableListeners( m_aMutex )
408     ,m_nOverrideExecutionResult( -1 )
409 {
410 }
411 
412 //-------------------------------------------------------------------------
~CopyTableWizard()413 CopyTableWizard::~CopyTableWizard()
414 {
415     acquire();
416 
417     // protect some members whose dtor might potentially throw
418     try { m_xSourceConnection.clear();  }
419     catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
420     try { m_xDestConnection.clear();  }
421     catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
422 
423     // TODO: shouldn't we have explicit disposal support? If a listener is registered
424     // at our instance, and perhaps holds this our instance by a hard ref, then we'll never
425     // be destroyed.
426     // However, adding XComponent support to the GenericUNODialog probably requires
427     // some thinking - would it break existing clients which do not call a dispose, then?
428 }
429 
430 //-------------------------------------------------------------------------
Create(const Reference<XMultiServiceFactory> & _rxFactory)431 Reference< XInterface > CopyTableWizard::Create( const Reference< XMultiServiceFactory >& _rxFactory )
432 {
433     return *( new CopyTableWizard( _rxFactory ) );
434 }
435 
436 //-------------------------------------------------------------------------
getImplementationName()437 ::rtl::OUString SAL_CALL CopyTableWizard::getImplementationName() throw(RuntimeException)
438 {
439     return getImplementationName_Static();
440 }
441 
442 //-------------------------------------------------------------------------
getImplementationName_Static()443 ::rtl::OUString CopyTableWizard::getImplementationName_Static() throw(RuntimeException)
444 {
445     return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.dbu.CopyTableWizard" ) );
446 }
447 
448 //-------------------------------------------------------------------------
getSupportedServiceNames()449 ::comphelper::StringSequence SAL_CALL CopyTableWizard::getSupportedServiceNames() throw(RuntimeException)
450 {
451     return getSupportedServiceNames_Static();
452 }
453 
454 //-------------------------------------------------------------------------
getSupportedServiceNames_Static()455 ::comphelper::StringSequence CopyTableWizard::getSupportedServiceNames_Static() throw(RuntimeException)
456 {
457     ::comphelper::StringSequence aSupported(1);
458     aSupported.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.application.CopyTableWizard" ) );
459     return aSupported;
460 }
461 
462 //-------------------------------------------------------------------------
getPropertySetInfo()463 Reference< XPropertySetInfo > SAL_CALL CopyTableWizard::getPropertySetInfo() throw(RuntimeException)
464 {
465     Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
466     return xInfo;
467 }
468 
469 //--------------------------------------------------------------------
getOperation()470 ::sal_Int16 SAL_CALL CopyTableWizard::getOperation() throw (RuntimeException)
471 {
472     CopyTableAccessGuard aGuard( *this );
473     return m_nOperation;
474 }
475 
476 //--------------------------------------------------------------------
setOperation(::sal_Int16 _operation)477 void SAL_CALL CopyTableWizard::setOperation( ::sal_Int16 _operation ) throw (IllegalArgumentException, RuntimeException)
478 {
479     CopyTableAccessGuard aGuard( *this );
480 
481     if  (   ( _operation != CopyTableOperation::CopyDefinitionAndData )
482         &&  ( _operation != CopyTableOperation::CopyDefinitionOnly )
483         &&  ( _operation != CopyTableOperation::CreateAsView )
484         &&  ( _operation != CopyTableOperation::AppendData )
485         )
486         throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
487 
488     if  (   ( _operation == CopyTableOperation::CreateAsView )
489         &&  !OCopyTableWizard::supportsViews( m_xDestConnection )
490         )
491         throw IllegalArgumentException(
492             String( ModuleRes( STR_CTW_NO_VIEWS_SUPPORT ) ),
493             *this,
494             1
495         );
496 
497     m_nOperation = _operation;
498 }
499 
500 //--------------------------------------------------------------------
getDestinationTableName()501 ::rtl::OUString SAL_CALL CopyTableWizard::getDestinationTableName() throw (RuntimeException)
502 {
503     CopyTableAccessGuard aGuard( *this );
504     return m_sDestinationTable;
505 }
506 
507 //--------------------------------------------------------------------
setDestinationTableName(const::rtl::OUString & _destinationTableName)508 void SAL_CALL CopyTableWizard::setDestinationTableName( const ::rtl::OUString& _destinationTableName ) throw (RuntimeException)
509 {
510     CopyTableAccessGuard aGuard( *this );
511     m_sDestinationTable = _destinationTableName;
512 }
513 
514 //--------------------------------------------------------------------
getCreatePrimaryKey()515 Optional< ::rtl::OUString > SAL_CALL CopyTableWizard::getCreatePrimaryKey() throw (RuntimeException)
516 {
517     CopyTableAccessGuard aGuard( *this );
518     return m_aPrimaryKeyName;
519 }
520 
521 //--------------------------------------------------------------------
setCreatePrimaryKey(const Optional<::rtl::OUString> & _newPrimaryKey)522 void SAL_CALL CopyTableWizard::setCreatePrimaryKey( const Optional< ::rtl::OUString >& _newPrimaryKey ) throw (IllegalArgumentException, RuntimeException)
523 {
524     CopyTableAccessGuard aGuard( *this );
525 
526     if ( _newPrimaryKey.IsPresent && !OCopyTableWizard::supportsPrimaryKey( m_xDestConnection ) )
527         throw IllegalArgumentException(
528                 String( ModuleRes( STR_CTW_NO_PRIMARY_KEY_SUPPORT ) ),
529             *this,
530             1
531         );
532 
533     m_aPrimaryKeyName = _newPrimaryKey;
534 }
535 // -----------------------------------------------------------------------------
getUseHeaderLineAsColumnNames()536 sal_Bool SAL_CALL CopyTableWizard::getUseHeaderLineAsColumnNames() throw (RuntimeException)
537 {
538     CopyTableAccessGuard aGuard( *this );
539     return m_bUseHeaderLineAsColumnNames;
540 }
541 // -----------------------------------------------------------------------------
setUseHeaderLineAsColumnNames(sal_Bool _bUseHeaderLineAsColumnNames)542 void SAL_CALL CopyTableWizard::setUseHeaderLineAsColumnNames( sal_Bool _bUseHeaderLineAsColumnNames ) throw (RuntimeException)
543 {
544     CopyTableAccessGuard aGuard( *this );
545     m_bUseHeaderLineAsColumnNames = _bUseHeaderLineAsColumnNames;
546 }
547 //--------------------------------------------------------------------
addCopyTableListener(const Reference<XCopyTableListener> & _rxListener)548 void SAL_CALL CopyTableWizard::addCopyTableListener( const Reference< XCopyTableListener >& _rxListener ) throw (RuntimeException)
549 {
550     CopyTableAccessGuard aGuard( *this );
551     if ( _rxListener.is() )
552         m_aCopyTableListeners.addInterface( _rxListener );
553 }
554 
555 //--------------------------------------------------------------------
removeCopyTableListener(const Reference<XCopyTableListener> & _rxListener)556 void SAL_CALL CopyTableWizard::removeCopyTableListener( const Reference< XCopyTableListener >& _rxListener ) throw (RuntimeException)
557 {
558     CopyTableAccessGuard aGuard( *this );
559     if ( _rxListener.is() )
560         m_aCopyTableListeners.removeInterface( _rxListener );
561 }
562 
563 //--------------------------------------------------------------------
setTitle(const::rtl::OUString & _rTitle)564 void SAL_CALL CopyTableWizard::setTitle( const ::rtl::OUString& _rTitle ) throw (RuntimeException)
565 {
566     CopyTableAccessGuard aGuard( *this );
567     CopyTableWizard_DialogBase::setTitle( _rTitle );
568 }
569 
570 //--------------------------------------------------------------------
execute()571 ::sal_Int16 SAL_CALL CopyTableWizard::execute(  ) throw (RuntimeException)
572 {
573     CopyTableAccessGuard aGuard( *this );
574 
575     m_nOverrideExecutionResult = -1;
576     sal_Int16 nExecutionResult = CopyTableWizard_DialogBase::execute();
577     if ( m_nOverrideExecutionResult )
578         nExecutionResult = m_nOverrideExecutionResult;
579 
580     return nExecutionResult;
581 }
582 
583 //-------------------------------------------------------------------------
impl_getDialog_throw()584 OCopyTableWizard& CopyTableWizard::impl_getDialog_throw()
585 {
586     OCopyTableWizard* pWizard = dynamic_cast< OCopyTableWizard* >( m_pDialog );
587     if ( !pWizard )
588         throw DisposedException( ::rtl::OUString(), *this );
589     return *pWizard;
590 }
591 
592 //-------------------------------------------------------------------------
impl_getDialog_throw() const593 const OCopyTableWizard& CopyTableWizard::impl_getDialog_throw() const
594 {
595     const OCopyTableWizard* pWizard = dynamic_cast< const OCopyTableWizard* >( m_pDialog );
596     if ( !pWizard )
597         throw DisposedException( ::rtl::OUString(), *const_cast< CopyTableWizard* >( this ) );
598     return *pWizard;
599 }
600 
601 //-------------------------------------------------------------------------
impl_attributesToDialog_nothrow(OCopyTableWizard & _rDialog) const602 void CopyTableWizard::impl_attributesToDialog_nothrow( OCopyTableWizard& _rDialog ) const
603 {
604     // primary key column
605     _rDialog.setCreatePrimaryKey( m_aPrimaryKeyName.IsPresent, m_aPrimaryKeyName.Value );
606     _rDialog.setUseHeaderLine(m_bUseHeaderLineAsColumnNames);
607 
608     // everything else was passed at construction time already
609 }
610 
611 //-------------------------------------------------------------------------
impl_dialogToAttributes_nothrow(const OCopyTableWizard & _rDialog)612 void CopyTableWizard::impl_dialogToAttributes_nothrow( const OCopyTableWizard& _rDialog )
613 {
614     m_aPrimaryKeyName.IsPresent = _rDialog.shouldCreatePrimaryKey();
615     if ( m_aPrimaryKeyName.IsPresent )
616         m_aPrimaryKeyName.Value = _rDialog.getPrimaryKeyName();
617     else
618         m_aPrimaryKeyName.Value = ::rtl::OUString();
619 
620     m_sDestinationTable = _rDialog.getName();
621 
622     m_nOperation = _rDialog.getOperation();
623     m_bUseHeaderLineAsColumnNames = _rDialog.UseHeaderLine();
624 }
625 
626 //-------------------------------------------------------------------------
627 namespace
628 {
629     //.....................................................................
630     /** tries to obtain the InteractionHandler associated with a given data source
631 
632         If the data source is a sdb-level data source, it will have a DatabaseDocument associated
633         with it. This doocument may have an InteractionHandler used while loading it.
634 
635         @throws RuntimeException
636             if it occurs during invoking any of the data source's methods, or if any of the involved
637             components violates its contract by not providing the required interfaces
638     */
lcl_getInteractionHandler_throw(const Reference<XDataSource> & _rxDataSource,const InteractionHandler & _rFallback)639     InteractionHandler lcl_getInteractionHandler_throw( const Reference< XDataSource >& _rxDataSource, const InteractionHandler& _rFallback )
640     {
641         InteractionHandler xHandler( _rFallback );
642 
643         // try to obtain the document model
644         Reference< XModel > xDocumentModel;
645         Reference< XDocumentDataSource > xDocDataSource( _rxDataSource, UNO_QUERY );
646         if ( xDocDataSource.is() )
647             xDocumentModel.set( xDocDataSource->getDatabaseDocument(), UNO_QUERY_THROW );
648 
649         // see whether the document model can provide a handler
650         if ( xDocumentModel.is() )
651         {
652             ::comphelper::NamedValueCollection aModelArgs( xDocumentModel->getArgs() );
653             xHandler = aModelArgs.getOrDefault( "InteractionHandler", xHandler );
654         }
655 
656         return xHandler;
657     }
658     //.....................................................................
659     /** tries to obtain the InteractionHandler associated with a given connection
660 
661         If the connection belongs to a sdb-level data source, then this data source
662         is examined for an interaction handler. Else, <NULL/> is returned.
663 
664         @throws RuntimeException
665             if it occurs during invoking any of the data source's methods, or if any of the involved
666             components violates its contract by not providing the required interfaces
667     */
lcl_getInteractionHandler_throw(const Reference<XConnection> & _rxConnection,const InteractionHandler & _rFallback)668     InteractionHandler lcl_getInteractionHandler_throw( const Reference< XConnection >& _rxConnection, const InteractionHandler& _rFallback )
669     {
670         // try whether there is a data source which the connection belongs to
671         Reference< XDataSource > xDataSource;
672         Reference< XChild > xAsChild( _rxConnection, UNO_QUERY );
673         if ( xAsChild.is() )
674             xDataSource = xDataSource.query( xAsChild->getParent() );
675 
676         if ( xDataSource.is() )
677             return lcl_getInteractionHandler_throw( xDataSource, _rFallback );
678 
679         return _rFallback;
680     }
681 }
682 
683 //-------------------------------------------------------------------------
impl_ensureDataAccessDescriptor_throw(const Sequence<Any> & _rAllArgs,const sal_Int16 _nArgPos,SharedConnection & _out_rxConnection,InteractionHandler & _out_rxDocInteractionHandler) const684 Reference< XPropertySet > CopyTableWizard::impl_ensureDataAccessDescriptor_throw(
685     const Sequence< Any >& _rAllArgs, const sal_Int16 _nArgPos, SharedConnection& _out_rxConnection,
686     InteractionHandler& _out_rxDocInteractionHandler ) const
687 {
688     Reference< XPropertySet > xDescriptor;
689     _rAllArgs[ _nArgPos ] >>= xDescriptor;
690 
691     // the descriptor must be non-NULL, of course
692     bool bIsValid = xDescriptor.is();
693 
694     // it must support the proper service
695     if ( bIsValid )
696     {
697         Reference< XServiceInfo > xSI( xDescriptor, UNO_QUERY );
698         bIsValid =  (   xSI.is()
699                     &&  xSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.DataAccessDescriptor" ) ) )
700                     );
701     }
702 
703     // it must be able to provide a connection
704     if ( bIsValid )
705     {
706         _out_rxConnection = impl_extractConnection_throw( xDescriptor, _out_rxDocInteractionHandler );
707         bIsValid = _out_rxConnection.is();
708     }
709 
710     if ( !bIsValid )
711     {
712         throw IllegalArgumentException(
713             String( ModuleRes( STR_CTW_INVALID_DATA_ACCESS_DESCRIPTOR ) ),
714             *const_cast< CopyTableWizard* >( this ),
715             _nArgPos + 1
716         );
717     }
718 
719     return xDescriptor;
720 }
721 
722 //-------------------------------------------------------------------------
723 namespace
724 {
lcl_hasNonEmptyStringValue_throw(const Reference<XPropertySet> & _rxDescriptor,const Reference<XPropertySetInfo> _rxPSI,const::rtl::OUString & _rPropertyName)725     bool lcl_hasNonEmptyStringValue_throw( const Reference< XPropertySet >& _rxDescriptor,
726         const Reference< XPropertySetInfo > _rxPSI, const ::rtl::OUString& _rPropertyName )
727     {
728         ::rtl::OUString sValue;
729         if ( _rxPSI->hasPropertyByName( _rPropertyName ) )
730         {
731             OSL_VERIFY( _rxDescriptor->getPropertyValue( _rPropertyName ) >>= sValue );
732         }
733         return sValue.getLength() > 0;
734     }
735 }
736 
737 //-------------------------------------------------------------------------
impl_checkForUnsupportedSettings_throw(const Reference<XPropertySet> & _rxSourceDescriptor) const738 void CopyTableWizard::impl_checkForUnsupportedSettings_throw( const Reference< XPropertySet >& _rxSourceDescriptor ) const
739 {
740     OSL_PRECOND( _rxSourceDescriptor.is(), "CopyTableWizard::impl_checkForUnsupportedSettings_throw: illegal argument!" );
741     Reference< XPropertySetInfo > xPSI( _rxSourceDescriptor->getPropertySetInfo(), UNO_SET_THROW );
742     ::rtl::OUString sUnsupportedSetting;
743 
744     const ::rtl::OUString aSettings[] = {
745         PROPERTY_FILTER, PROPERTY_ORDER, PROPERTY_HAVING_CLAUSE, PROPERTY_GROUP_BY
746     };
747     for ( size_t i=0; i < sizeof( aSettings ) / sizeof( aSettings[0] ); ++i )
748     {
749         if ( lcl_hasNonEmptyStringValue_throw( _rxSourceDescriptor, xPSI, aSettings[i] ) )
750         {
751             sUnsupportedSetting = aSettings[i];
752             break;
753         }
754     }
755 
756     if ( sUnsupportedSetting.getLength() != 0 )
757     {
758         ::rtl::OUString sMessage( String(ModuleRes( STR_CTW_ERROR_UNSUPPORTED_SETTING )) );
759         ::comphelper::string::searchAndReplaceAsciiI( sMessage, "$name$", sUnsupportedSetting );
760         throw IllegalArgumentException(
761             sMessage,
762             *const_cast< CopyTableWizard* >( this ),
763             1
764         );
765     }
766 
767 }
768 
769 //-------------------------------------------------------------------------
impl_extractSourceObject_throw(const Reference<XPropertySet> & _rxDescriptor,sal_Int32 & _out_rCommandType) const770 ::std::auto_ptr< ICopyTableSourceObject > CopyTableWizard::impl_extractSourceObject_throw( const Reference< XPropertySet >& _rxDescriptor, sal_Int32& _out_rCommandType ) const
771 {
772     OSL_PRECOND( _rxDescriptor.is() && m_xSourceConnection.is(), "CopyTableWizard::impl_extractSourceObject_throw: illegal arguments!" );
773 
774     Reference< XPropertySetInfo > xPSI( _rxDescriptor->getPropertySetInfo(), UNO_SET_THROW );
775     if  (   !xPSI->hasPropertyByName( PROPERTY_COMMAND )
776         ||  !xPSI->hasPropertyByName( PROPERTY_COMMAND_TYPE )
777         )
778         throw IllegalArgumentException(
779             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Expecting a table or query specification." ) ),
780                 // TODO: resource
781             *const_cast< CopyTableWizard* >( this ),
782             1
783         );
784 
785     ::rtl::OUString sCommand;
786     _out_rCommandType = CommandType::COMMAND;
787     OSL_VERIFY( _rxDescriptor->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand );
788     OSL_VERIFY( _rxDescriptor->getPropertyValue( PROPERTY_COMMAND_TYPE ) >>= _out_rCommandType );
789 
790     ::std::auto_ptr< ICopyTableSourceObject > pSourceObject;
791     Reference< XNameAccess > xContainer;
792     switch ( _out_rCommandType )
793     {
794     case CommandType::TABLE:
795     {
796         Reference< XTablesSupplier > xSuppTables( m_xSourceConnection.getTyped(), UNO_QUERY );
797         if ( xSuppTables.is() )
798             xContainer.set( xSuppTables->getTables(), UNO_SET_THROW );
799     }
800     break;
801     case CommandType::QUERY:
802     {
803         Reference< XQueriesSupplier > xSuppQueries( m_xSourceConnection.getTyped(), UNO_QUERY );
804         if ( xSuppQueries.is() )
805             xContainer.set( xSuppQueries->getQueries(), UNO_SET_THROW );
806     }
807     break;
808     default:
809         throw IllegalArgumentException(
810             String( ModuleRes( STR_CTW_ONLY_TABLES_AND_QUERIES_SUPPORT ) ),
811             *const_cast< CopyTableWizard* >( this ),
812             1
813         );
814     }
815 
816     if ( xContainer.is() )
817     {
818         pSourceObject.reset( new ObjectCopySource( m_xSourceConnection,
819             Reference< XPropertySet >( xContainer->getByName( sCommand ), UNO_QUERY_THROW ) ) );
820     }
821     else
822     {
823         // our source connection is an SDBC level connection only, not a SDBCX level one
824         // Which means it cannot provide the to-be-copied object as component.
825 
826         if ( _out_rCommandType == CommandType::QUERY )
827             // we cannot copy a query if the connection cannot provide it ...
828             throw IllegalArgumentException(
829                 String(ModuleRes( STR_CTW_ERROR_NO_QUERY )),
830                 *const_cast< CopyTableWizard* >( this ),
831                 1
832             );
833         pSourceObject.reset( new NamedTableCopySource( m_xSourceConnection, sCommand ) );
834     }
835 
836     return pSourceObject;
837 }
838 
839 //-------------------------------------------------------------------------
impl_extractSourceResultSet_throw(const Reference<XPropertySet> & i_rDescriptor)840 void CopyTableWizard::impl_extractSourceResultSet_throw( const Reference< XPropertySet >& i_rDescriptor )
841 {
842     Reference< XPropertySetInfo > xPSI( i_rDescriptor->getPropertySetInfo(), UNO_SET_THROW );
843 
844     // extract relevant settings
845     if ( xPSI->hasPropertyByName( PROPERTY_RESULT_SET ) )
846         m_xSourceResultSet.set( i_rDescriptor->getPropertyValue( PROPERTY_RESULT_SET ), UNO_QUERY );
847 
848     if ( xPSI->hasPropertyByName( PROPERTY_SELECTION ) )
849         OSL_VERIFY( i_rDescriptor->getPropertyValue( PROPERTY_SELECTION ) >>= m_aSourceSelection );
850 
851     if ( xPSI->hasPropertyByName( PROPERTY_BOOKMARK_SELECTION ) )
852         OSL_VERIFY( i_rDescriptor->getPropertyValue( PROPERTY_BOOKMARK_SELECTION ) >>= m_bSourceSelectionBookmarks );
853 
854     // sanity checks
855     const bool bHasResultSet = m_xSourceResultSet.is();
856     const bool bHasSelection = ( m_aSourceSelection.getLength() != 0 );
857     if ( bHasSelection && !bHasResultSet )
858         throw IllegalArgumentException(
859             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "A result set is needed when specifying a selection to copy." ) ),
860                 // TODO: resource
861             *this,
862             1
863         );
864 
865     if ( bHasSelection && m_bSourceSelectionBookmarks )
866     {
867         Reference< XRowLocate > xRowLocate( m_xSourceResultSet, UNO_QUERY );
868         if ( !xRowLocate.is() )
869         {
870             ::dbtools::throwGenericSQLException(
871                 String( ModuleRes( STR_CTW_COPY_SOURCE_NEEDS_BOOKMARKS ) ),
872                 *this
873             );
874         }
875     }
876 }
877 
878 //-------------------------------------------------------------------------
impl_extractConnection_throw(const Reference<XPropertySet> & _rxDataSourceDescriptor,InteractionHandler & _out_rxDocInteractionHandler) const879 SharedConnection CopyTableWizard::impl_extractConnection_throw( const Reference< XPropertySet >& _rxDataSourceDescriptor,
880     InteractionHandler& _out_rxDocInteractionHandler ) const
881 {
882     SharedConnection xConnection;
883 
884     OSL_PRECOND( _rxDataSourceDescriptor.is(), "CopyTableWizard::impl_extractConnection_throw: no descriptor!" );
885     if ( !_rxDataSourceDescriptor.is() )
886         return xConnection;
887 
888     InteractionHandler xInteractionHandler;
889 
890     do
891     {
892     Reference< XPropertySetInfo > xPSI( _rxDataSourceDescriptor->getPropertySetInfo(), UNO_SET_THROW );
893 
894     // if there's an ActiveConnection, use it
895     if ( xPSI->hasPropertyByName( PROPERTY_ACTIVE_CONNECTION ) )
896     {
897         Reference< XConnection > xPure;
898         OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xPure );
899         xConnection.reset( xPure, SharedConnection::NoTakeOwnership );
900     }
901     if ( xConnection.is() )
902     {
903         xInteractionHandler = lcl_getInteractionHandler_throw( xConnection.getTyped(), m_xInteractionHandler );
904         OSL_POSTCOND( xInteractionHandler.is(), "CopyTableWizard::impl_extractConnection_throw: lcl_getInteractionHandler_throw returned nonsense!" );
905         break;
906     }
907 
908     // there could be a DataSourceName or a DatabaseLocation, describing the css.sdb.DataSource
909     ::rtl::OUString sDataSource, sDatabaseLocation;
910     if ( xPSI->hasPropertyByName( PROPERTY_DATASOURCENAME ) )
911         OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_DATASOURCENAME ) >>= sDataSource );
912     if ( xPSI->hasPropertyByName( PROPERTY_DATABASE_LOCATION ) )
913         OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_DATABASE_LOCATION ) >>= sDatabaseLocation );
914 
915     // need a DatabaseContext for loading the data source
916     Reference< XNameAccess > xDatabaseContext( m_aContext.createComponent( "com.sun.star.sdb.DatabaseContext" ), UNO_QUERY_THROW );
917     Reference< XDataSource > xDataSource;
918     if ( sDataSource.getLength() )
919         xDataSource.set( xDatabaseContext->getByName( sDataSource ), UNO_QUERY_THROW );
920     if ( !xDataSource.is() && sDatabaseLocation.getLength() )
921         xDataSource.set( xDatabaseContext->getByName( sDatabaseLocation ), UNO_QUERY_THROW );
922 
923     if ( xDataSource.is() )
924     {
925         // first, try connecting with completion
926         xInteractionHandler = lcl_getInteractionHandler_throw( xDataSource, m_xInteractionHandler );
927         OSL_POSTCOND( xInteractionHandler.is(), "CopyTableWizard::impl_extractConnection_throw: lcl_getInteractionHandler_throw returned nonsense!" );
928         if ( xInteractionHandler.is() )
929         {
930             Reference< XCompletedConnection > xInteractiveConnection( xDataSource, UNO_QUERY );
931             if ( xInteractiveConnection.is() )
932                 xConnection.reset( xInteractiveConnection->connectWithCompletion( xInteractionHandler ), SharedConnection::TakeOwnership );
933         }
934 
935         // interactively connecting was not successful or possible -> connect without interaction
936         if ( !xConnection.is() )
937         {
938             xConnection.reset( xDataSource->getConnection( ::rtl::OUString(), ::rtl::OUString() ), SharedConnection::TakeOwnership );
939         }
940     }
941 
942     if ( xConnection.is() )
943         break;
944 
945     // finally, there could be a ConnectionResource/ConnectionInfo
946     ::rtl::OUString sConnectionResource;
947     Sequence< PropertyValue > aConnectionInfo;
948     if ( xPSI->hasPropertyByName( PROPERTY_CONNECTION_RESOURCE ) )
949         OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_CONNECTION_RESOURCE ) >>= sConnectionResource );
950     if ( xPSI->hasPropertyByName( PROPERTY_CONNECTION_INFO ) )
951         OSL_VERIFY( _rxDataSourceDescriptor->getPropertyValue( PROPERTY_CONNECTION_INFO ) >>= aConnectionInfo );
952 
953     Reference< XDriverManager > xDriverManager;
954     xDriverManager.set( m_aContext.createComponent( "com.sun.star.sdbc.ConnectionPool" ), UNO_QUERY );
955     if ( !xDriverManager.is() )
956         // no connection pool installed
957         xDriverManager.set( m_aContext.createComponent( "com.sun.star.sdbc.DriverManager" ), UNO_QUERY_THROW );
958 
959     if ( aConnectionInfo.getLength() )
960         xConnection.set( xDriverManager->getConnectionWithInfo( sConnectionResource, aConnectionInfo ), UNO_SET_THROW );
961     else
962         xConnection.set( xDriverManager->getConnection( sConnectionResource ), UNO_SET_THROW );
963     }
964     while ( false );
965 
966     if ( xInteractionHandler != m_xInteractionHandler )
967         _out_rxDocInteractionHandler = xInteractionHandler;
968 
969     return xConnection;
970 }
971 
972 //-------------------------------------------------------------------------
impl_createSourceStatement_throw() const973 ::utl::SharedUNOComponent< XPreparedStatement > CopyTableWizard::impl_createSourceStatement_throw() const
974 {
975     OSL_PRECOND( m_xSourceConnection.is(), "CopyTableWizard::impl_createSourceStatement_throw: illegal call!" );
976     if ( !m_xSourceConnection.is() )
977         throw RuntimeException( ::rtl::OUString(), *const_cast< CopyTableWizard* >( this ) );
978 
979     ::utl::SharedUNOComponent< XPreparedStatement > xStatement;
980     switch ( m_nCommandType )
981     {
982     case CommandType::TABLE:
983         xStatement.set( m_pSourceObject->getPreparedSelectStatement(), UNO_SET_THROW );
984         break;
985 
986     case CommandType::QUERY:
987     {
988         ::rtl::OUString sQueryCommand( m_pSourceObject->getSelectStatement() );
989         xStatement.set( m_pSourceObject->getPreparedSelectStatement(), UNO_SET_THROW );
990 
991         // check whether we have to fill in parameter values
992         // create and fill a composer
993 
994         Reference< XMultiServiceFactory > xFactory( m_xSourceConnection, UNO_QUERY );
995         ::utl::SharedUNOComponent< XSingleSelectQueryComposer > xComposer;
996         if ( xFactory.is() )
997             // note: connections below the sdb-level are allowed to not support the XMultiServiceFactory interface
998             xComposer.set( xFactory->createInstance( SERVICE_NAME_SINGLESELECTQUERYCOMPOSER ), UNO_QUERY );
999 
1000         if ( xComposer.is() )
1001         {
1002             xComposer->setQuery( sQueryCommand );
1003 
1004             Reference< XParameters > xStatementParams( xStatement, UNO_QUERY );
1005             OSL_ENSURE( xStatementParams.is(), "CopyTableWizard::impl_createSourceStatement_throw: no access to the statement's parameters!" );
1006                 // the statement should be a css.sdbc.PreparedStatement (this is what
1007                 // we created), and a prepared statement is required to support XParameters
1008             if ( xStatementParams.is() )
1009             {
1010                 OSL_ENSURE( m_xInteractionHandler.is(),
1011                    "CopyTableWizard::impl_createSourceStatement_throw: no interaction handler for the parameters request!" );
1012                 // we should always have an interaction handler - as last fallback, we create an own one in ::initialize
1013 
1014                 if ( m_xInteractionHandler.is() )
1015                     ::dbtools::askForParameters( xComposer, xStatementParams, m_xSourceConnection, m_xInteractionHandler );
1016             }
1017         }
1018     }
1019     break;
1020 
1021     default:
1022         // this should not have survived initialization phase
1023         throw RuntimeException( ::rtl::OUString(), *const_cast< CopyTableWizard* >( this ) );
1024     }
1025 
1026     return xStatement;
1027 }
1028 
1029 //-------------------------------------------------------------------------
1030 namespace
1031 {
1032     class ValueTransfer
1033     {
1034     public:
ValueTransfer(const sal_Int32 & _rSourcePos,const sal_Int32 & _rDestPos,const::std::vector<sal_Int32> & _rColTypes,const Reference<XRow> & _rxSource,const Reference<XParameters> & _rxDest)1035         ValueTransfer( const sal_Int32& _rSourcePos, const sal_Int32& _rDestPos, const ::std::vector< sal_Int32 >& _rColTypes,
1036             const Reference< XRow >& _rxSource, const Reference< XParameters >& _rxDest )
1037             :m_rSourcePos( _rSourcePos )
1038             ,m_rDestPos( _rDestPos )
1039             ,m_rColTypes( _rColTypes )
1040             ,m_xSource( _rxSource )
1041             ,m_xDest( _rxDest )
1042         {
1043         }
1044 
1045     template< typename VALUE_TYPE >
transferValue(VALUE_TYPE (SAL_CALL XRow::* _pGetter)(sal_Int32),void (SAL_CALL XParameters::* _pSetter)(sal_Int32,VALUE_TYPE))1046     void transferValue( VALUE_TYPE ( SAL_CALL XRow::*_pGetter )( sal_Int32 ),
1047         void (SAL_CALL XParameters::*_pSetter)( sal_Int32, VALUE_TYPE ) )
1048     {
1049         VALUE_TYPE value( (m_xSource.get()->*_pGetter)( m_rSourcePos ) );
1050         if ( m_xSource->wasNull() )
1051             m_xDest->setNull( m_rDestPos, m_rColTypes[ m_rSourcePos ] );
1052         else
1053             (m_xDest.get()->*_pSetter)( m_rDestPos, value );
1054     }
1055  template< typename VALUE_TYPE >
transferComplexValue(VALUE_TYPE (SAL_CALL XRow::* _pGetter)(sal_Int32),void (SAL_CALL XParameters::* _pSetter)(sal_Int32,const VALUE_TYPE &))1056     void transferComplexValue( VALUE_TYPE ( SAL_CALL XRow::*_pGetter )( sal_Int32 ),
1057         void (SAL_CALL XParameters::*_pSetter)( sal_Int32, const VALUE_TYPE& ) )
1058     {
1059         const VALUE_TYPE value( (m_xSource.get()->*_pGetter)( m_rSourcePos ) );
1060                {
1061         if ( m_xSource->wasNull() )
1062             m_xDest->setNull( m_rDestPos, m_rColTypes[ m_rSourcePos ] );
1063         else
1064             (m_xDest.get()->*_pSetter)( m_rDestPos, value );
1065                }
1066     }
1067     private:
1068         const sal_Int32&                    m_rSourcePos;
1069         const sal_Int32&                    m_rDestPos;
1070         const ::std::vector< sal_Int32 >    m_rColTypes;
1071         const Reference< XRow >             m_xSource;
1072         const Reference< XParameters >      m_xDest;
1073     };
1074 }
1075 
1076 //-------------------------------------------------------------------------
impl_processCopyError_nothrow(const CopyTableRowEvent & _rEvent)1077 bool CopyTableWizard::impl_processCopyError_nothrow( const CopyTableRowEvent& _rEvent )
1078 {
1079     Reference< XCopyTableListener > xListener;
1080     try
1081     {
1082         ::cppu::OInterfaceIteratorHelper aIter( m_aCopyTableListeners );
1083         while ( aIter.hasMoreElements() )
1084         {
1085             xListener.set( aIter.next(), UNO_QUERY_THROW );
1086             sal_Int16 nListenerChoice = xListener->copyRowError( _rEvent );
1087             switch ( nListenerChoice )
1088             {
1089             case CopyTableContinuation::Proceed:            return true;    // continue copying
1090             case CopyTableContinuation::CallNextHandler:    continue;       // continue the loop, ask next listener
1091             case CopyTableContinuation::Cancel:             return false;   // cancel copying
1092             case CopyTableContinuation::AskUser:            break;          // stop asking the listeners, ask the user
1093 
1094             default:
1095                 OSL_ENSURE( false, "CopyTableWizard::impl_processCopyError_nothrow: invalid listener response!" );
1096                 // ask next listener
1097                 continue;
1098             }
1099         }
1100     }
1101     catch( const Exception& )
1102     {
1103     	DBG_UNHANDLED_EXCEPTION();
1104     }
1105 
1106     // no listener felt responsible for the error, or a listener told to ask the user
1107 
1108     try
1109     {
1110         SQLContext aError;
1111         aError.Context = *this;
1112         aError.Message = String( ModuleRes( STR_ERROR_OCCURED_WHILE_COPYING ) );
1113 
1114         ::dbtools::SQLExceptionInfo aInfo( _rEvent.Error );
1115         if ( aInfo.isValid() )
1116             aError.NextException = _rEvent.Error;
1117         else
1118         {
1119             // a non-SQL exception happened
1120             Exception aException;
1121             OSL_VERIFY( _rEvent.Error >>= aException );
1122             SQLContext aContext;
1123             aContext.Context = aException.Context;
1124             aContext.Message = aException.Message;
1125             aContext.Details = _rEvent.Error.getValueTypeName();
1126             aError.NextException <<= aContext;
1127         }
1128 
1129         ::rtl::Reference< ::comphelper::OInteractionRequest > xRequest( new ::comphelper::OInteractionRequest( makeAny( aError ) ) );
1130 
1131         ::rtl::Reference< ::comphelper::OInteractionApprove > xYes = new ::comphelper::OInteractionApprove;
1132         xRequest->addContinuation( xYes.get() );
1133         xRequest->addContinuation( new ::comphelper::OInteractionDisapprove );
1134 
1135         OSL_ENSURE( m_xInteractionHandler.is(),
1136             "CopyTableWizard::impl_processCopyError_nothrow: we always should have an interaction handler!" );
1137         if ( m_xInteractionHandler.is() )
1138             m_xInteractionHandler->handle( xRequest.get() );
1139 
1140         if ( xYes->wasSelected() )
1141             // continue copying
1142             return true;
1143     }
1144     catch( const Exception& )
1145     {
1146     	DBG_UNHANDLED_EXCEPTION();
1147     }
1148 
1149     // cancel copying
1150     return false;
1151 }
1152 
1153 //-------------------------------------------------------------------------
impl_copyRows_throw(const Reference<XResultSet> & _rxSourceResultSet,const Reference<XPropertySet> & _rxDestTable)1154 void CopyTableWizard::impl_copyRows_throw( const Reference< XResultSet >& _rxSourceResultSet,
1155     const Reference< XPropertySet >& _rxDestTable )
1156 {
1157     OSL_PRECOND( m_xDestConnection.is(), "CopyTableWizard::impl_copyRows_throw: illegal call!" );
1158     if ( !m_xDestConnection.is() )
1159         throw RuntimeException( ::rtl::OUString(), *this );
1160 
1161     Reference< XDatabaseMetaData > xDestMetaData( m_xDestConnection->getMetaData(), UNO_QUERY_THROW );
1162 
1163     const OCopyTableWizard& rWizard             = impl_getDialog_throw();
1164     ODatabaseExport::TPositions aColumnMapping  = rWizard.GetColumnPositions();
1165     bool bAutoIncrement                         = rWizard.shouldCreatePrimaryKey();
1166 
1167     Reference< XRow > xRow              ( _rxSourceResultSet, UNO_QUERY_THROW );
1168     Reference< XRowLocate > xRowLocate  ( _rxSourceResultSet, UNO_QUERY_THROW );
1169 
1170     Reference< XResultSetMetaDataSupplier > xSuppResMeta( _rxSourceResultSet, UNO_QUERY_THROW );
1171     Reference< XResultSetMetaData> xMeta( xSuppResMeta->getMetaData() );
1172 
1173     // we need a vector which all types
1174     sal_Int32 nCount = xMeta->getColumnCount();
1175     ::std::vector< sal_Int32 > aSourceColTypes;
1176     aSourceColTypes.reserve( nCount + 1 );
1177     aSourceColTypes.push_back( -1 ); // just to avoid a every time i-1 call
1178 
1179     ::std::vector< sal_Int32 > aSourcePrec;
1180     aSourcePrec.reserve( nCount + 1 );
1181     aSourcePrec.push_back( -1 ); // just to avoid a every time i-1 call
1182 
1183     for ( sal_Int32 k=1; k <= nCount; ++k )
1184     {
1185         aSourceColTypes.push_back( xMeta->getColumnType( k ) );
1186         aSourcePrec.push_back( xMeta->getPrecision( k ) );
1187     }
1188 
1189     // now create, fill and execute the prepared statement
1190     Reference< XPreparedStatement > xStatement( ODatabaseExport::createPreparedStatment( xDestMetaData, _rxDestTable, aColumnMapping ), UNO_SET_THROW );
1191     Reference< XParameters > xStatementParams( xStatement, UNO_QUERY_THROW );
1192 
1193     const bool bSelectedRecordsOnly = m_aSourceSelection.getLength() != 0;
1194     const Any* pSelectedRow         = m_aSourceSelection.getConstArray();
1195     const Any* pSelEnd              = pSelectedRow + m_aSourceSelection.getLength();
1196 
1197     sal_Int32 nRowCount = 0;
1198     bool bContinue = false;
1199 
1200     CopyTableRowEvent aCopyEvent;
1201     aCopyEvent.Source = *this;
1202     aCopyEvent.SourceData = _rxSourceResultSet;
1203 
1204     do // loop as long as there are more rows or the selection ends
1205     {
1206         bContinue = false;
1207         if ( bSelectedRecordsOnly )
1208         {
1209             if ( pSelectedRow != pSelEnd )
1210             {
1211                 if ( m_bSourceSelectionBookmarks )
1212                 {
1213                     bContinue = xRowLocate->moveToBookmark( *pSelectedRow );
1214                 }
1215                 else
1216                 {
1217                     sal_Int32 nPos = 0;
1218                     OSL_VERIFY( *pSelectedRow >>= nPos );
1219                     bContinue = _rxSourceResultSet->absolute( nPos );
1220                 }
1221                 ++pSelectedRow;
1222             }
1223         }
1224         else
1225             bContinue = _rxSourceResultSet->next();
1226 
1227         if ( !bContinue )
1228 		{
1229             break;
1230 		}
1231 
1232         ++nRowCount;
1233         sal_Bool bInsertAutoIncrement = sal_True;
1234         ODatabaseExport::TPositions::const_iterator aPosIter = aColumnMapping.begin();
1235         ODatabaseExport::TPositions::const_iterator aPosEnd = aColumnMapping.end();
1236 
1237         aCopyEvent.Error.clear();
1238         try
1239         {
1240             // notify listeners
1241             m_aCopyTableListeners.notifyEach( &XCopyTableListener::copyingRow, aCopyEvent );
1242 
1243             sal_Int32 nDestColumn( 0 );
1244             sal_Int32 nSourceColumn( 1 );
1245 			ValueTransfer aTransfer( nSourceColumn, nDestColumn, aSourceColTypes, xRow, xStatementParams );
1246 
1247             for ( ; aPosIter != aPosEnd; ++aPosIter )
1248             {
1249                 nDestColumn = aPosIter->first;
1250                 if ( nDestColumn == COLUMN_POSITION_NOT_FOUND )
1251                 {
1252                     ++nSourceColumn;
1253                     // otherwise we don't get the correct value when only the 2nd source column was selected
1254                     continue;
1255                 }
1256 
1257                 if ( bAutoIncrement && bInsertAutoIncrement )
1258                 {
1259                     xStatementParams->setInt( 1, nRowCount );
1260                     bInsertAutoIncrement = sal_False;
1261                     continue;
1262                 }
1263 
1264                 if ( ( nSourceColumn < 1 ) || ( nSourceColumn >= (sal_Int32)aSourceColTypes.size() ) )
1265                 {   // ( we have to check here against 1 because the parameters are 1 based)
1266                     ::dbtools::throwSQLException(
1267                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Internal error: invalid column type index." ) ),
1268                         ::dbtools::SQL_INVALID_DESCRIPTOR_INDEX,
1269                         *this
1270                     );
1271                 }
1272 
1273                 switch ( aSourceColTypes[ nSourceColumn ] )
1274                 {
1275                     case DataType::DOUBLE:
1276                     case DataType::REAL:
1277                         aTransfer.transferValue( &XRow::getDouble, &XParameters::setDouble );
1278                         break;
1279 
1280                     case DataType::CHAR:
1281                     case DataType::VARCHAR:
1282                     case DataType::LONGVARCHAR:
1283                     case DataType::DECIMAL:
1284                     case DataType::NUMERIC:
1285                         aTransfer.transferComplexValue( &XRow::getString, &XParameters::setString );
1286                         break;
1287 
1288                     case DataType::BIGINT:
1289                         aTransfer.transferValue( &XRow::getLong, &XParameters::setLong );
1290                         break;
1291 
1292                     case DataType::FLOAT:
1293                         aTransfer.transferValue( &XRow::getFloat, &XParameters::setFloat );
1294                         break;
1295 
1296                     case DataType::LONGVARBINARY:
1297                     case DataType::BINARY:
1298                     case DataType::VARBINARY:
1299                         aTransfer.transferComplexValue( &XRow::getBytes, &XParameters::setBytes );
1300                         break;
1301 
1302                     case DataType::DATE:
1303                         aTransfer.transferComplexValue( &XRow::getDate, &XParameters::setDate );
1304                         break;
1305 
1306                     case DataType::TIME:
1307                         aTransfer.transferComplexValue( &XRow::getTime, &XParameters::setTime );
1308                         break;
1309 
1310                     case DataType::TIMESTAMP:
1311                         aTransfer.transferComplexValue( &XRow::getTimestamp, &XParameters::setTimestamp );
1312                         break;
1313 
1314                     case DataType::BIT:
1315                         if ( aSourcePrec[nSourceColumn] > 1 )
1316                         {
1317                             aTransfer.transferComplexValue( &XRow::getBytes, &XParameters::setBytes );
1318                             break;
1319                         }
1320                         // run through
1321                     case DataType::BOOLEAN:
1322                         aTransfer.transferValue( &XRow::getBoolean, &XParameters::setBoolean );
1323                         break;
1324 
1325                     case DataType::TINYINT:
1326                         aTransfer.transferValue( &XRow::getByte, &XParameters::setByte );
1327                         break;
1328 
1329                     case DataType::SMALLINT:
1330                         aTransfer.transferValue( &XRow::getShort, &XParameters::setShort );
1331                         break;
1332 
1333                     case DataType::INTEGER:
1334                         aTransfer.transferValue( &XRow::getInt, &XParameters::setInt );
1335                         break;
1336 
1337 					case DataType::BLOB:
1338                         aTransfer.transferComplexValue( &XRow::getBlob, &XParameters::setBlob );
1339                         break;
1340 
1341 					case DataType::CLOB:
1342                         aTransfer.transferComplexValue( &XRow::getClob, &XParameters::setClob );
1343                         break;
1344 
1345                     default:
1346                     {
1347                         ::rtl::OUString aMessage( String( ModuleRes( STR_CTW_UNSUPPORTED_COLUMN_TYPE ) ) );
1348 
1349                         aMessage.replaceAt( aMessage.indexOfAsciiL( "$type$", 6 ), 6, ::rtl::OUString::valueOf( aSourceColTypes[ nSourceColumn ] ) );
1350                         aMessage.replaceAt( aMessage.indexOfAsciiL( "$pos$", 5 ), 5, ::rtl::OUString::valueOf( nSourceColumn ) );
1351 
1352                         ::dbtools::throwSQLException(
1353                             aMessage,
1354                             ::dbtools::SQL_INVALID_SQL_DATA_TYPE,
1355                             *this
1356                         );
1357                     }
1358                 }
1359                 ++nSourceColumn;
1360             }
1361             xStatement->executeUpdate();
1362 
1363             // notify listeners
1364             m_aCopyTableListeners.notifyEach( &XCopyTableListener::copiedRow, aCopyEvent );
1365         }
1366         catch( const Exception& )
1367         {
1368             aCopyEvent.Error = ::cppu::getCaughtException();
1369         }
1370 
1371         if ( aCopyEvent.Error.hasValue() )
1372             bContinue = impl_processCopyError_nothrow( aCopyEvent );
1373     }
1374     while( bContinue );
1375 }
1376 //-------------------------------------------------------------------------
impl_doCopy_nothrow()1377 void CopyTableWizard::impl_doCopy_nothrow()
1378 {
1379     Any aError;
1380 
1381     try
1382     {
1383         OCopyTableWizard& rWizard( impl_getDialog_throw() );
1384 
1385         WaitObject aWO( rWizard.GetParent() );
1386         Reference< XPropertySet > xTable;
1387 
1388         switch ( rWizard.getOperation() )
1389         {
1390             case CopyTableOperation::CopyDefinitionOnly:
1391             case CopyTableOperation::CopyDefinitionAndData:
1392             {
1393                 xTable = rWizard.createTable();
1394 
1395                 if( !xTable.is() )
1396                 {
1397                     OSL_ENSURE( false, "CopyTableWizard::impl_doCopy_nothrow: createTable should throw here, shouldn't it?" );
1398                     break;
1399                 }
1400 
1401                 if( CopyTableOperation::CopyDefinitionOnly == rWizard.getOperation() )
1402                     break;
1403             }
1404             // run through
1405 
1406             case CopyTableOperation::AppendData:
1407             {
1408 
1409                 if ( !xTable.is() )
1410                 {
1411                     xTable = rWizard.createTable();
1412                     if ( !xTable.is() )
1413                     {
1414                         OSL_ENSURE( false, "CopyTableWizard::impl_doCopy_nothrow: createTable should throw here, shouldn't it?" );
1415                         break;
1416                     }
1417                 }
1418 
1419                 ::utl::SharedUNOComponent< XPreparedStatement > xSourceStatement;
1420                 ::utl::SharedUNOComponent< XResultSet > xSourceResultSet;
1421 
1422                 if ( m_xSourceResultSet.is() )
1423                 {
1424                     xSourceResultSet.reset( m_xSourceResultSet, ::utl::SharedUNOComponent< XResultSet >::NoTakeOwnership );
1425                 }
1426                 else
1427                 {
1428                     const bool bIsSameConnection = ( m_xSourceConnection.getTyped() == m_xDestConnection.getTyped() );
1429                     const bool bIsTable = ( CommandType::TABLE == m_nCommandType );
1430                     bool bDone = false;
1431                     if ( bIsSameConnection && bIsTable )
1432                     {
1433                         // try whether the server supports copying via SQL
1434                         try
1435                         {
1436                             m_xDestConnection->createStatement()->executeUpdate( impl_getServerSideCopyStatement_throw(xTable) );
1437                             bDone = true;
1438                         }
1439                         catch( const Exception& )
1440                         {
1441                             // this is allowed.
1442                         }
1443                     }
1444 
1445                     if ( !bDone )
1446                     {
1447                         xSourceStatement.set( impl_createSourceStatement_throw(), UNO_SET_THROW );
1448                         xSourceResultSet.set( xSourceStatement->executeQuery(), UNO_SET_THROW );
1449                     }
1450                 }
1451 
1452                 if ( xSourceResultSet.is() )
1453                     impl_copyRows_throw( xSourceResultSet, xTable );
1454             }
1455             break;
1456 
1457             case CopyTableOperation::CreateAsView:
1458                 rWizard.createView();
1459                 break;
1460 
1461             default:
1462                 OSL_ENSURE( false, "CopyTableWizard::impl_doCopy_nothrow: What operation, please?" );
1463                 break;
1464         }
1465     }
1466     catch( const Exception& )
1467     {
1468         aError = ::cppu::getCaughtException();
1469 
1470         // silence the error of the user cancelling the parameter's dialog
1471         SQLException aSQLError;
1472         if ( ( aError >>= aSQLError ) && ( aSQLError.ErrorCode == ::dbtools::ParameterInteractionCancelled ) )
1473         {
1474             aError.clear();
1475             m_nOverrideExecutionResult = RET_CANCEL;
1476         }
1477     }
1478 
1479     if ( aError.hasValue() && m_xInteractionHandler.is() )
1480     {
1481         try
1482         {
1483             ::rtl::Reference< ::comphelper::OInteractionRequest > xRequest( new ::comphelper::OInteractionRequest( aError ) );
1484             m_xInteractionHandler->handle( xRequest.get() );
1485         }
1486         catch( const Exception& )
1487         {
1488         	DBG_UNHANDLED_EXCEPTION();
1489         }
1490     }
1491 }
1492 // -----------------------------------------------------------------------------
impl_getServerSideCopyStatement_throw(const Reference<XPropertySet> & _xTable)1493 ::rtl::OUString CopyTableWizard::impl_getServerSideCopyStatement_throw(const Reference< XPropertySet >& _xTable)
1494 {
1495     const Reference<XColumnsSupplier> xDestColsSup(_xTable,UNO_QUERY_THROW);
1496 	const Sequence< ::rtl::OUString> aDestColumnNames = xDestColsSup->getColumns()->getElementNames();
1497     const Sequence< ::rtl::OUString > aColumnNames = m_pSourceObject->getColumnNames();
1498     const Reference< XDatabaseMetaData > xDestMetaData( m_xDestConnection->getMetaData(), UNO_QUERY_THROW );
1499     const ::rtl::OUString sQuote = xDestMetaData->getIdentifierQuoteString();
1500     ::rtl::OUStringBuffer sColumns;
1501     // 1st check if the columns matching
1502     const OCopyTableWizard& rWizard             = impl_getDialog_throw();
1503     ODatabaseExport::TPositions aColumnMapping  = rWizard.GetColumnPositions();
1504     ODatabaseExport::TPositions::const_iterator aPosIter = aColumnMapping.begin();
1505     for ( sal_Int32 i = 0; aPosIter != aColumnMapping.end() ; ++aPosIter,++i )
1506     {
1507         if ( COLUMN_POSITION_NOT_FOUND != aPosIter->second )
1508         {
1509             if ( sColumns.getLength() )
1510                 sColumns.appendAscii(",");
1511             sColumns.append(sQuote);
1512             sColumns.append(aDestColumnNames[aPosIter->second - 1]);
1513             sColumns.append(sQuote);
1514         }
1515     } // for ( ; aPosIter != aColumnMapping.end() ; ++aPosIter )
1516     ::rtl::OUStringBuffer sSql;
1517     sSql.appendAscii("INSERT INTO ");
1518     const ::rtl::OUString sComposedTableName = ::dbtools::composeTableName( xDestMetaData, _xTable, ::dbtools::eInDataManipulation, false, false, true );
1519     sSql.append( sComposedTableName );
1520     sSql.appendAscii(" ( ");
1521     sSql.append( sColumns );
1522     sSql.appendAscii(" ) ( ");
1523     sSql.append( m_pSourceObject->getSelectStatement());
1524     sSql.appendAscii(" )");
1525 
1526     return sSql.makeStringAndClear();
1527 }
1528 //-------------------------------------------------------------------------
initialize(const Sequence<Any> & _rArguments)1529 void SAL_CALL CopyTableWizard::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException)
1530 {
1531     ::osl::MutexGuard aGuard( m_aMutex );
1532     if ( isInitialized() )
1533         throw AlreadyInitializedException( ::rtl::OUString(), *this );
1534 
1535     sal_Int32 nArgCount( _rArguments.getLength() );
1536     if ( ( nArgCount != 2 ) && ( nArgCount != 3 ) )
1537         throw IllegalArgumentException(
1538             String( ModuleRes( STR_CTW_ILLEGAL_PARAMETER_COUNT ) ),
1539             *this,
1540             1
1541         );
1542 
1543     try
1544     {
1545         if ( nArgCount == 3 )
1546         {   // ->createWithInteractionHandler
1547             if ( !( _rArguments[2] >>= m_xInteractionHandler ) )
1548                 throw IllegalArgumentException(
1549                     String(ModuleRes( STR_CTW_ERROR_INVALID_INTERACTIONHANDLER )),
1550                     *this,
1551                     3
1552                 );
1553         }
1554         if ( !m_xInteractionHandler.is() )
1555             m_xInteractionHandler.set( m_aContext.createComponent( "com.sun.star.task.InteractionHandler" ), UNO_QUERY_THROW );
1556 
1557         InteractionHandler xSourceDocHandler;
1558         Reference< XPropertySet > xSourceDescriptor( impl_ensureDataAccessDescriptor_throw( _rArguments, 0, m_xSourceConnection, xSourceDocHandler ) );
1559         impl_checkForUnsupportedSettings_throw( xSourceDescriptor );
1560         m_pSourceObject = impl_extractSourceObject_throw( xSourceDescriptor, m_nCommandType );
1561         impl_extractSourceResultSet_throw( xSourceDescriptor );
1562 
1563         InteractionHandler xDestDocHandler;
1564         impl_ensureDataAccessDescriptor_throw( _rArguments, 1, m_xDestConnection, xDestDocHandler );
1565 
1566         if ( xDestDocHandler.is() && !m_xInteractionHandler.is() )
1567             m_xInteractionHandler = xDestDocHandler;
1568     }
1569     catch( const RuntimeException& ) { throw; }
1570     catch( const IllegalArgumentException& ) { throw; }
1571     catch( const SQLException& ) { throw; }
1572     catch( const Exception& )
1573     {
1574         throw WrappedTargetException(
1575             String( ModuleRes( STR_CTW_ERROR_DURING_INITIALIZATION ) ),
1576             *this,
1577             ::cppu::getCaughtException()
1578         );
1579     }
1580 }
1581 
1582 //-------------------------------------------------------------------------
getInfoHelper()1583 ::cppu::IPropertyArrayHelper& CopyTableWizard::getInfoHelper()
1584 {
1585     return *getArrayHelper();
1586 }
1587 
1588 //------------------------------------------------------------------------------
createArrayHelper() const1589 ::cppu::IPropertyArrayHelper* CopyTableWizard::createArrayHelper( ) const
1590 {
1591     Sequence< Property > aProps;
1592     describeProperties( aProps );
1593     return new ::cppu::OPropertyArrayHelper( aProps );
1594 }
1595 
1596 //------------------------------------------------------------------------------
createDialog(Window * _pParent)1597 Dialog*	CopyTableWizard::createDialog( Window* _pParent )
1598 {
1599     OSL_PRECOND( isInitialized(), "CopyTableWizard::createDialog: not initialized!" );
1600         // this should have been prevented in ::execute already
1601 
1602     OCopyTableWizard* pWizard = new OCopyTableWizard(
1603         _pParent,
1604         m_sDestinationTable,
1605         m_nOperation,
1606         *m_pSourceObject,
1607         m_xSourceConnection.getTyped(),
1608         m_xDestConnection.getTyped(),
1609         m_aContext.getLegacyServiceFactory(),
1610         m_xInteractionHandler
1611     );
1612 
1613     impl_attributesToDialog_nothrow( *pWizard );
1614 
1615     return pWizard;
1616 }
1617 
1618 //------------------------------------------------------------------------------
executedDialog(sal_Int16 _nExecutionResult)1619 void CopyTableWizard::executedDialog( sal_Int16 _nExecutionResult )
1620 {
1621     CopyTableWizard_DialogBase::executedDialog( _nExecutionResult );
1622 
1623     if ( _nExecutionResult == RET_OK )
1624         impl_doCopy_nothrow();
1625 
1626     // do this after impl_doCopy_nothrow: The attributes may change during copying, for instance
1627     // if the user entered an unqualified table name
1628     impl_dialogToAttributes_nothrow( impl_getDialog_throw() );
1629 }
1630 
1631 //........................................................................
1632 } // namespace dbaui
1633 //........................................................................
1634 
createRegistryInfo_CopyTableWizard()1635 extern "C" void SAL_CALL createRegistryInfo_CopyTableWizard()
1636 {
1637     static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::CopyTableWizard > aAutoRegistration;
1638 }
1639