xref: /trunk/main/ucb/source/core/ucbcmds.cxx (revision 86e1cf34)
12f86921cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
32f86921cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
42f86921cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
52f86921cSAndrew Rist  * distributed with this work for additional information
62f86921cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
72f86921cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
82f86921cSAndrew Rist  * "License"); you may not use this file except in compliance
92f86921cSAndrew Rist  * with the License.  You may obtain a copy of the License at
102f86921cSAndrew Rist  *
112f86921cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
122f86921cSAndrew Rist  *
132f86921cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
142f86921cSAndrew Rist  * software distributed under the License is distributed on an
152f86921cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
162f86921cSAndrew Rist  * KIND, either express or implied.  See the License for the
172f86921cSAndrew Rist  * specific language governing permissions and limitations
182f86921cSAndrew Rist  * under the License.
192f86921cSAndrew Rist  *
202f86921cSAndrew Rist  *************************************************************/
212f86921cSAndrew Rist 
222f86921cSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_ucb.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir /**************************************************************************
28cdf0e10cSrcweir                                 TODO
29cdf0e10cSrcweir  **************************************************************************
30cdf0e10cSrcweir 
31cdf0e10cSrcweir  *************************************************************************/
32cdf0e10cSrcweir #include <osl/diagnose.h>
33cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
34cdf0e10cSrcweir #include <cppuhelper/exc_hlp.hxx>
35cdf0e10cSrcweir #include <rtl/ustring.h>
36cdf0e10cSrcweir #include <rtl/ustring.hxx>
37cdf0e10cSrcweir #include <com/sun/star/uno/XInterface.hpp>
38cdf0e10cSrcweir #include <com/sun/star/beans/PropertyState.hpp>
39cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp>
40cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
41cdf0e10cSrcweir #include <com/sun/star/container/XChild.hpp>
42cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySetInfo.hpp>
43cdf0e10cSrcweir #include <com/sun/star/io/XActiveDataSink.hpp>
44cdf0e10cSrcweir #include <com/sun/star/io/XOutputStream.hpp>
45cdf0e10cSrcweir #include <com/sun/star/io/XSeekable.hpp>
46cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp>
47cdf0e10cSrcweir #include <com/sun/star/task/XInteractionHandler.hpp>
48cdf0e10cSrcweir #include <com/sun/star/ucb/CommandEnvironment.hpp>
49cdf0e10cSrcweir #include <com/sun/star/ucb/CommandFailedException.hpp>
50cdf0e10cSrcweir #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
51cdf0e10cSrcweir #include <com/sun/star/ucb/GlobalTransferCommandArgument.hpp>
52cdf0e10cSrcweir #include <com/sun/star/ucb/InsertCommandArgument.hpp>
53cdf0e10cSrcweir #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
54cdf0e10cSrcweir #include <com/sun/star/ucb/NameClash.hpp>
55cdf0e10cSrcweir #include <com/sun/star/ucb/NameClashException.hpp>
56cdf0e10cSrcweir #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
57cdf0e10cSrcweir #include <com/sun/star/ucb/OpenMode.hpp>
58cdf0e10cSrcweir #include <com/sun/star/ucb/TransferInfo.hpp>
59cdf0e10cSrcweir #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
60cdf0e10cSrcweir #include <com/sun/star/ucb/XCommandInfo.hpp>
61cdf0e10cSrcweir #include <com/sun/star/ucb/XContentAccess.hpp>
62cdf0e10cSrcweir #include <com/sun/star/ucb/XContentCreator.hpp>
63cdf0e10cSrcweir #include <com/sun/star/ucb/XDynamicResultSet.hpp>
64cdf0e10cSrcweir #include <com/sun/star/uno/Any.hxx>
65cdf0e10cSrcweir #include <com/sun/star/uno/Sequence.hxx>
66cdf0e10cSrcweir #include <ucbhelper/cancelcommandexecution.hxx>
67cdf0e10cSrcweir #include <ucbhelper/simplenameclashresolverequest.hxx>
68cdf0e10cSrcweir #include "ucbcmds.hxx"
69cdf0e10cSrcweir #include "ucb.hxx"
70cdf0e10cSrcweir 
71cdf0e10cSrcweir using namespace com::sun::star;
72cdf0e10cSrcweir 
73cdf0e10cSrcweir namespace
74cdf0e10cSrcweir {
75cdf0e10cSrcweir 
76cdf0e10cSrcweir //=========================================================================
77cdf0e10cSrcweir //
78cdf0e10cSrcweir // struct TransferCommandContext.
79cdf0e10cSrcweir //
80cdf0e10cSrcweir //=========================================================================
81cdf0e10cSrcweir 
82cdf0e10cSrcweir struct TransferCommandContext
83cdf0e10cSrcweir {
84cdf0e10cSrcweir     uno::Reference< lang::XMultiServiceFactory > xSMgr;
85cdf0e10cSrcweir     uno::Reference< ucb::XCommandProcessor >     xProcessor;
86cdf0e10cSrcweir     uno::Reference< ucb::XCommandEnvironment >   xEnv;
87cdf0e10cSrcweir     uno::Reference< ucb::XCommandEnvironment >   xOrigEnv;
88cdf0e10cSrcweir     ucb::GlobalTransferCommandArgument           aArg;
89cdf0e10cSrcweir 
TransferCommandContext__anone98597310111::TransferCommandContext90cdf0e10cSrcweir     TransferCommandContext(
91cdf0e10cSrcweir         const uno::Reference< lang::XMultiServiceFactory > & rxSMgr,
92cdf0e10cSrcweir         const uno::Reference< ucb::XCommandProcessor > & rxProcessor,
93cdf0e10cSrcweir         const uno::Reference< ucb::XCommandEnvironment > & rxEnv,
94cdf0e10cSrcweir         const uno::Reference< ucb::XCommandEnvironment > & rxOrigEnv,
95cdf0e10cSrcweir         const ucb::GlobalTransferCommandArgument & rArg )
96cdf0e10cSrcweir     : xSMgr( rxSMgr ), xProcessor( rxProcessor ), xEnv( rxEnv ),
97cdf0e10cSrcweir       xOrigEnv( rxOrigEnv ), aArg( rArg ) {}
98cdf0e10cSrcweir };
99cdf0e10cSrcweir 
100cdf0e10cSrcweir //=========================================================================
101cdf0e10cSrcweir //
102cdf0e10cSrcweir // class InteractionHandlerProxy.
103cdf0e10cSrcweir //
104cdf0e10cSrcweir //=========================================================================
105cdf0e10cSrcweir 
106cdf0e10cSrcweir class InteractionHandlerProxy :
107cdf0e10cSrcweir     public cppu::WeakImplHelper1< task::XInteractionHandler >
108cdf0e10cSrcweir {
109cdf0e10cSrcweir     uno::Reference< task::XInteractionHandler > m_xOrig;
110cdf0e10cSrcweir 
111cdf0e10cSrcweir public:
InteractionHandlerProxy(const uno::Reference<task::XInteractionHandler> & xOrig)112cdf0e10cSrcweir     InteractionHandlerProxy(
113cdf0e10cSrcweir         const uno::Reference< task::XInteractionHandler > & xOrig )
114cdf0e10cSrcweir     : m_xOrig( xOrig ) {}
115cdf0e10cSrcweir 
116cdf0e10cSrcweir     // XInteractionHandler methods.
117cdf0e10cSrcweir     virtual void SAL_CALL handle(
118cdf0e10cSrcweir             const uno::Reference< task::XInteractionRequest >& Request )
119cdf0e10cSrcweir         throw ( uno::RuntimeException );
120cdf0e10cSrcweir };
121cdf0e10cSrcweir 
122cdf0e10cSrcweir //=========================================================================
123cdf0e10cSrcweir // virtual
handle(const uno::Reference<task::XInteractionRequest> & Request)124cdf0e10cSrcweir void SAL_CALL InteractionHandlerProxy::handle(
125cdf0e10cSrcweir             const uno::Reference< task::XInteractionRequest >& Request )
126cdf0e10cSrcweir     throw ( uno::RuntimeException )
127cdf0e10cSrcweir {
128cdf0e10cSrcweir     if ( !m_xOrig.is() )
129cdf0e10cSrcweir         return;
130cdf0e10cSrcweir 
131cdf0e10cSrcweir     // Filter unwanted requests by just not handling them.
132cdf0e10cSrcweir     uno::Any aRequest = Request->getRequest();
133cdf0e10cSrcweir 
134cdf0e10cSrcweir     // "transfer"
135cdf0e10cSrcweir     ucb::InteractiveBadTransferURLException aBadTransferURLEx;
136cdf0e10cSrcweir     if ( aRequest >>= aBadTransferURLEx )
137cdf0e10cSrcweir     {
138cdf0e10cSrcweir         return;
139cdf0e10cSrcweir     }
140cdf0e10cSrcweir     else
141cdf0e10cSrcweir     {
142cdf0e10cSrcweir         // "transfer"
143cdf0e10cSrcweir         ucb::UnsupportedNameClashException aUnsupportedNameClashEx;
144cdf0e10cSrcweir         if ( aRequest >>= aUnsupportedNameClashEx )
145cdf0e10cSrcweir         {
146cdf0e10cSrcweir             if ( aUnsupportedNameClashEx.NameClash
147cdf0e10cSrcweir                     != ucb::NameClash::ERROR )
148cdf0e10cSrcweir                 return;
149cdf0e10cSrcweir         }
150cdf0e10cSrcweir         else
151cdf0e10cSrcweir         {
152cdf0e10cSrcweir             // "insert"
153cdf0e10cSrcweir             ucb::NameClashException aNameClashEx;
154cdf0e10cSrcweir             if ( aRequest >>= aNameClashEx )
155cdf0e10cSrcweir             {
156cdf0e10cSrcweir                 return;
157cdf0e10cSrcweir             }
158cdf0e10cSrcweir             else
159cdf0e10cSrcweir             {
160cdf0e10cSrcweir                 // "transfer"
161cdf0e10cSrcweir                 ucb::UnsupportedCommandException aUnsupportedCommandEx;
162cdf0e10cSrcweir                 if ( aRequest >>= aUnsupportedCommandEx )
163cdf0e10cSrcweir                 {
164cdf0e10cSrcweir                     return;
165cdf0e10cSrcweir                 }
166cdf0e10cSrcweir             }
167cdf0e10cSrcweir         }
168cdf0e10cSrcweir     }
169cdf0e10cSrcweir 
170cdf0e10cSrcweir     // not filtered; let the original handler do the work.
171cdf0e10cSrcweir     m_xOrig->handle( Request );
172cdf0e10cSrcweir }
173cdf0e10cSrcweir 
174cdf0e10cSrcweir //=========================================================================
175cdf0e10cSrcweir //
176cdf0e10cSrcweir // class ActiveDataSink.
177cdf0e10cSrcweir //
178cdf0e10cSrcweir //=========================================================================
179cdf0e10cSrcweir 
180cdf0e10cSrcweir class ActiveDataSink : public cppu::WeakImplHelper1< io::XActiveDataSink >
181cdf0e10cSrcweir {
182cdf0e10cSrcweir     uno::Reference< io::XInputStream > m_xStream;
183cdf0e10cSrcweir 
184cdf0e10cSrcweir public:
185cdf0e10cSrcweir     // XActiveDataSink methods.
186cdf0e10cSrcweir     virtual void SAL_CALL setInputStream(
187cdf0e10cSrcweir                         const uno::Reference< io::XInputStream >& aStream )
188cdf0e10cSrcweir         throw( uno::RuntimeException );
189cdf0e10cSrcweir     virtual uno::Reference< io::XInputStream > SAL_CALL getInputStream()
190cdf0e10cSrcweir         throw( uno::RuntimeException );
191cdf0e10cSrcweir };
192cdf0e10cSrcweir 
193cdf0e10cSrcweir //=========================================================================
194cdf0e10cSrcweir // virtual
setInputStream(const uno::Reference<io::XInputStream> & aStream)195cdf0e10cSrcweir void SAL_CALL ActiveDataSink::setInputStream(
196cdf0e10cSrcweir                         const uno::Reference< io::XInputStream >& aStream )
197cdf0e10cSrcweir     throw( uno::RuntimeException )
198cdf0e10cSrcweir {
199cdf0e10cSrcweir     m_xStream = aStream;
200cdf0e10cSrcweir }
201cdf0e10cSrcweir 
202cdf0e10cSrcweir //=========================================================================
203cdf0e10cSrcweir // virtual
getInputStream()204cdf0e10cSrcweir uno::Reference< io::XInputStream > SAL_CALL ActiveDataSink::getInputStream()
205cdf0e10cSrcweir     throw( uno::RuntimeException )
206cdf0e10cSrcweir {
207cdf0e10cSrcweir     return m_xStream;
208cdf0e10cSrcweir }
209cdf0e10cSrcweir 
210cdf0e10cSrcweir //=========================================================================
211cdf0e10cSrcweir //
212cdf0e10cSrcweir // class CommandProcessorInfo.
213cdf0e10cSrcweir //
214cdf0e10cSrcweir //=========================================================================
215cdf0e10cSrcweir 
216cdf0e10cSrcweir class CommandProcessorInfo :
217cdf0e10cSrcweir     public cppu::WeakImplHelper1< ucb::XCommandInfo >
218cdf0e10cSrcweir {
219cdf0e10cSrcweir     uno::Sequence< ucb::CommandInfo > * m_pInfo;
220cdf0e10cSrcweir 
221cdf0e10cSrcweir public:
222cdf0e10cSrcweir     CommandProcessorInfo();
223cdf0e10cSrcweir     virtual ~CommandProcessorInfo();
224cdf0e10cSrcweir 
225cdf0e10cSrcweir     // XCommandInfo methods
226cdf0e10cSrcweir     virtual uno::Sequence< ucb::CommandInfo > SAL_CALL getCommands()
227cdf0e10cSrcweir         throw( uno::RuntimeException );
228cdf0e10cSrcweir     virtual ucb::CommandInfo SAL_CALL
229cdf0e10cSrcweir     getCommandInfoByName( const rtl::OUString& Name )
230cdf0e10cSrcweir         throw( ucb::UnsupportedCommandException, uno::RuntimeException );
231cdf0e10cSrcweir     virtual ucb::CommandInfo SAL_CALL
232cdf0e10cSrcweir     getCommandInfoByHandle( sal_Int32 Handle )
233cdf0e10cSrcweir         throw( ucb::UnsupportedCommandException, uno::RuntimeException );
234cdf0e10cSrcweir     virtual sal_Bool SAL_CALL hasCommandByName( const rtl::OUString& Name )
235cdf0e10cSrcweir         throw( uno::RuntimeException );
236cdf0e10cSrcweir     virtual sal_Bool SAL_CALL hasCommandByHandle( sal_Int32 Handle )
237cdf0e10cSrcweir         throw( uno::RuntimeException );
238cdf0e10cSrcweir };
239cdf0e10cSrcweir 
240cdf0e10cSrcweir //=========================================================================
CommandProcessorInfo()241cdf0e10cSrcweir CommandProcessorInfo::CommandProcessorInfo()
242cdf0e10cSrcweir {
243cdf0e10cSrcweir     m_pInfo = new uno::Sequence< ucb::CommandInfo >( 2 );
244cdf0e10cSrcweir 
245cdf0e10cSrcweir     (*m_pInfo)[ 0 ]
246cdf0e10cSrcweir         = ucb::CommandInfo(
247cdf0e10cSrcweir             rtl::OUString::createFromAscii( GETCOMMANDINFO_NAME ), // Name
248cdf0e10cSrcweir             GETCOMMANDINFO_HANDLE, // Handle
249cdf0e10cSrcweir             getCppuVoidType() ); // ArgType
250cdf0e10cSrcweir     (*m_pInfo)[ 1 ]
251cdf0e10cSrcweir         = ucb::CommandInfo(
252cdf0e10cSrcweir             rtl::OUString::createFromAscii( GLOBALTRANSFER_NAME ), // Name
253cdf0e10cSrcweir             GLOBALTRANSFER_HANDLE, // Handle
254cdf0e10cSrcweir             getCppuType(
255cdf0e10cSrcweir                 static_cast<
256cdf0e10cSrcweir                     ucb::GlobalTransferCommandArgument * >( 0 ) ) ); // ArgType
257cdf0e10cSrcweir }
258cdf0e10cSrcweir 
259cdf0e10cSrcweir //=========================================================================
260cdf0e10cSrcweir // virtual
~CommandProcessorInfo()261cdf0e10cSrcweir CommandProcessorInfo::~CommandProcessorInfo()
262cdf0e10cSrcweir {
263cdf0e10cSrcweir     delete m_pInfo;
264cdf0e10cSrcweir }
265cdf0e10cSrcweir 
266cdf0e10cSrcweir //=========================================================================
267cdf0e10cSrcweir // virtual
268cdf0e10cSrcweir uno::Sequence< ucb::CommandInfo > SAL_CALL
getCommands()269cdf0e10cSrcweir CommandProcessorInfo::getCommands()
270cdf0e10cSrcweir     throw( uno::RuntimeException )
271cdf0e10cSrcweir {
272cdf0e10cSrcweir     return uno::Sequence< ucb::CommandInfo >( *m_pInfo );
273cdf0e10cSrcweir }
274cdf0e10cSrcweir 
275cdf0e10cSrcweir //=========================================================================
276cdf0e10cSrcweir // virtual
277cdf0e10cSrcweir ucb::CommandInfo SAL_CALL
getCommandInfoByName(const rtl::OUString & Name)278cdf0e10cSrcweir CommandProcessorInfo::getCommandInfoByName( const rtl::OUString& Name )
279cdf0e10cSrcweir     throw( ucb::UnsupportedCommandException, uno::RuntimeException )
280cdf0e10cSrcweir {
281cdf0e10cSrcweir     for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n )
282cdf0e10cSrcweir     {
283cdf0e10cSrcweir         if ( (*m_pInfo)[ n ].Name == Name )
284cdf0e10cSrcweir             return ucb::CommandInfo( (*m_pInfo)[ n ] );
285cdf0e10cSrcweir     }
286cdf0e10cSrcweir 
287cdf0e10cSrcweir     throw ucb::UnsupportedCommandException();
288cdf0e10cSrcweir }
289cdf0e10cSrcweir 
290cdf0e10cSrcweir //=========================================================================
291cdf0e10cSrcweir // virtual
292cdf0e10cSrcweir ucb::CommandInfo SAL_CALL
getCommandInfoByHandle(sal_Int32 Handle)293cdf0e10cSrcweir CommandProcessorInfo::getCommandInfoByHandle( sal_Int32 Handle )
294cdf0e10cSrcweir     throw( ucb::UnsupportedCommandException, uno::RuntimeException )
295cdf0e10cSrcweir {
296cdf0e10cSrcweir     for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n )
297cdf0e10cSrcweir     {
298cdf0e10cSrcweir         if ( (*m_pInfo)[ n ].Handle == Handle )
299cdf0e10cSrcweir             return ucb::CommandInfo( (*m_pInfo)[ n ] );
300cdf0e10cSrcweir     }
301cdf0e10cSrcweir 
302cdf0e10cSrcweir     throw ucb::UnsupportedCommandException();
303cdf0e10cSrcweir }
304cdf0e10cSrcweir 
305cdf0e10cSrcweir //=========================================================================
306cdf0e10cSrcweir // virtual
hasCommandByName(const rtl::OUString & Name)307cdf0e10cSrcweir sal_Bool SAL_CALL CommandProcessorInfo::hasCommandByName(
308cdf0e10cSrcweir                                                 const rtl::OUString& Name )
309cdf0e10cSrcweir     throw( uno::RuntimeException )
310cdf0e10cSrcweir {
311cdf0e10cSrcweir     for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n )
312cdf0e10cSrcweir     {
313cdf0e10cSrcweir         if ( (*m_pInfo)[ n ].Name == Name )
314cdf0e10cSrcweir             return sal_True;
315cdf0e10cSrcweir     }
316cdf0e10cSrcweir 
317cdf0e10cSrcweir     return sal_False;
318cdf0e10cSrcweir }
319cdf0e10cSrcweir 
320cdf0e10cSrcweir //=========================================================================
321cdf0e10cSrcweir // virtual
hasCommandByHandle(sal_Int32 Handle)322cdf0e10cSrcweir sal_Bool SAL_CALL CommandProcessorInfo::hasCommandByHandle( sal_Int32 Handle )
323cdf0e10cSrcweir     throw( uno::RuntimeException )
324cdf0e10cSrcweir {
325cdf0e10cSrcweir     for ( sal_Int32 n = 0; n < m_pInfo->getLength(); ++n )
326cdf0e10cSrcweir     {
327cdf0e10cSrcweir         if ( (*m_pInfo)[ n ].Handle == Handle )
328cdf0e10cSrcweir             return sal_True;
329cdf0e10cSrcweir     }
330cdf0e10cSrcweir 
331cdf0e10cSrcweir     return sal_False;
332cdf0e10cSrcweir }
333cdf0e10cSrcweir 
334cdf0e10cSrcweir //=========================================================================
335cdf0e10cSrcweir //=========================================================================
336cdf0e10cSrcweir //=========================================================================
337cdf0e10cSrcweir 
createDesiredName(const rtl::OUString & rSourceURL,const rtl::OUString & rNewTitle)338cdf0e10cSrcweir rtl::OUString createDesiredName(
339cdf0e10cSrcweir     const rtl::OUString & rSourceURL, const rtl::OUString & rNewTitle )
340cdf0e10cSrcweir {
341cdf0e10cSrcweir     rtl::OUString aName( rNewTitle );
342cdf0e10cSrcweir     if ( aName.getLength() == 0 )
343cdf0e10cSrcweir     {
344cdf0e10cSrcweir         // calculate name using source URL
345cdf0e10cSrcweir 
346cdf0e10cSrcweir         // @@@ It's not guaranteed that slashes contained in the URL are
347cdf0e10cSrcweir         // actually path separators. This depends on the fact whether the
348cdf0e10cSrcweir         // URL is hierarchical. Only then the slashes are path separators.
349cdf0e10cSrcweir         // Therefore this algorithm is not guaranteed to work! But, ATM
350cdf0e10cSrcweir         // I don't know a better solution. It would have been better to
351cdf0e10cSrcweir         // have a member for the clashing name in
352cdf0e10cSrcweir         // UnsupportedNameClashException...
353cdf0e10cSrcweir 
354cdf0e10cSrcweir         sal_Int32 nLastSlash = rSourceURL.lastIndexOf( '/' );
355cdf0e10cSrcweir         bool bTrailingSlash = false;
356cdf0e10cSrcweir         if ( nLastSlash == rSourceURL.getLength() - 1 )
357cdf0e10cSrcweir         {
358cdf0e10cSrcweir             nLastSlash = rSourceURL.lastIndexOf( '/', nLastSlash );
359cdf0e10cSrcweir             bTrailingSlash = true;
360cdf0e10cSrcweir         }
361cdf0e10cSrcweir 
362cdf0e10cSrcweir         if ( nLastSlash != -1 )
363cdf0e10cSrcweir         {
364cdf0e10cSrcweir             if ( bTrailingSlash )
365cdf0e10cSrcweir                 aName = rSourceURL.copy(
366cdf0e10cSrcweir                             nLastSlash + 1,
367cdf0e10cSrcweir                             rSourceURL.getLength() - nLastSlash - 2 );
368cdf0e10cSrcweir             else
369cdf0e10cSrcweir                 aName = rSourceURL.copy( nLastSlash + 1 );
370cdf0e10cSrcweir         }
371cdf0e10cSrcweir         else
372cdf0e10cSrcweir         {
373cdf0e10cSrcweir             aName = rSourceURL;
374cdf0e10cSrcweir         }
375cdf0e10cSrcweir 
376cdf0e10cSrcweir         // query, fragment present?
377cdf0e10cSrcweir     sal_Int32  nPos = aName.indexOf( '?' );
378cdf0e10cSrcweir     if ( nPos == -1 )
379cdf0e10cSrcweir       nPos = aName.indexOf( '#' );
380cdf0e10cSrcweir 
381cdf0e10cSrcweir     if ( nPos != -1 )
382cdf0e10cSrcweir       aName = aName.copy( 0, nPos );
383cdf0e10cSrcweir     }
384cdf0e10cSrcweir     return rtl::OUString( aName );
385cdf0e10cSrcweir }
386cdf0e10cSrcweir 
createDesiredName(const ucb::GlobalTransferCommandArgument & rArg)387cdf0e10cSrcweir rtl::OUString createDesiredName(
388cdf0e10cSrcweir     const ucb::GlobalTransferCommandArgument & rArg )
389cdf0e10cSrcweir {
390cdf0e10cSrcweir     return createDesiredName( rArg.SourceURL, rArg.NewTitle );
391cdf0e10cSrcweir }
392cdf0e10cSrcweir 
createDesiredName(const ucb::TransferInfo & rArg)393cdf0e10cSrcweir rtl::OUString createDesiredName(
394cdf0e10cSrcweir     const ucb::TransferInfo & rArg )
395cdf0e10cSrcweir {
396cdf0e10cSrcweir     return createDesiredName( rArg.SourceURL, rArg.NewTitle );
397cdf0e10cSrcweir }
398cdf0e10cSrcweir 
399cdf0e10cSrcweir //=========================================================================
400cdf0e10cSrcweir enum NameClashContinuation { NOT_HANDLED, ABORT, OVERWRITE, NEW_NAME, UNKNOWN };
401cdf0e10cSrcweir 
interactiveNameClashResolve(const uno::Reference<ucb::XCommandEnvironment> & xEnv,const rtl::OUString & rTargetURL,const rtl::OUString & rClashingName,uno::Any & rException,rtl::OUString & rNewName)402cdf0e10cSrcweir NameClashContinuation interactiveNameClashResolve(
403cdf0e10cSrcweir     const uno::Reference< ucb::XCommandEnvironment > & xEnv,
404cdf0e10cSrcweir     const rtl::OUString & rTargetURL,
405cdf0e10cSrcweir     const rtl::OUString & rClashingName,
406cdf0e10cSrcweir     /* [out] */ uno::Any & rException,
407cdf0e10cSrcweir     /* [out] */ rtl::OUString & rNewName )
408cdf0e10cSrcweir {
409cdf0e10cSrcweir     rtl::Reference< ucbhelper::SimpleNameClashResolveRequest > xRequest(
410cdf0e10cSrcweir         new ucbhelper::SimpleNameClashResolveRequest(
411cdf0e10cSrcweir             rTargetURL,  // target folder URL
412cdf0e10cSrcweir             rClashingName,   // clashing name
413cdf0e10cSrcweir             rtl::OUString(), // no proposal for new name
414cdf0e10cSrcweir             sal_True /* bSupportsOverwriteData */ ) );
415cdf0e10cSrcweir 
416cdf0e10cSrcweir     rException = xRequest->getRequest();
417cdf0e10cSrcweir     if ( xEnv.is() )
418cdf0e10cSrcweir     {
419cdf0e10cSrcweir         uno::Reference< task::XInteractionHandler > xIH
420cdf0e10cSrcweir             = xEnv->getInteractionHandler();
421cdf0e10cSrcweir         if ( xIH.is() )
422cdf0e10cSrcweir         {
423cdf0e10cSrcweir 
424cdf0e10cSrcweir             xIH->handle( xRequest.get() );
425cdf0e10cSrcweir 
426cdf0e10cSrcweir             rtl::Reference< ucbhelper::InteractionContinuation >
427cdf0e10cSrcweir                 xSelection( xRequest->getSelection() );
428cdf0e10cSrcweir 
429cdf0e10cSrcweir             if ( xSelection.is() )
430cdf0e10cSrcweir             {
431cdf0e10cSrcweir                 // Handler handled the request.
432cdf0e10cSrcweir                 uno::Reference< task::XInteractionAbort > xAbort(
433cdf0e10cSrcweir                     xSelection.get(), uno::UNO_QUERY );
434cdf0e10cSrcweir                 if ( xAbort.is() )
435cdf0e10cSrcweir                 {
436cdf0e10cSrcweir                     // Abort.
437cdf0e10cSrcweir                     return ABORT;
438cdf0e10cSrcweir                 }
439cdf0e10cSrcweir                 else
440cdf0e10cSrcweir                 {
441cdf0e10cSrcweir                     uno::Reference<
442cdf0e10cSrcweir                         ucb::XInteractionReplaceExistingData >
443cdf0e10cSrcweir                             xReplace(
444cdf0e10cSrcweir                                 xSelection.get(), uno::UNO_QUERY );
445cdf0e10cSrcweir                     if ( xReplace.is() )
446cdf0e10cSrcweir                     {
447cdf0e10cSrcweir                         // Try again: Replace existing data.
448cdf0e10cSrcweir                         return OVERWRITE;
449cdf0e10cSrcweir                     }
450cdf0e10cSrcweir                     else
451cdf0e10cSrcweir                     {
452cdf0e10cSrcweir                         uno::Reference<
453cdf0e10cSrcweir                             ucb::XInteractionSupplyName >
454cdf0e10cSrcweir                                 xSupplyName(
455cdf0e10cSrcweir                                     xSelection.get(), uno::UNO_QUERY );
456cdf0e10cSrcweir                         if ( xSupplyName.is() )
457cdf0e10cSrcweir                         {
458cdf0e10cSrcweir                             // Try again: Use new name.
459cdf0e10cSrcweir                             rNewName = xRequest->getNewName();
460cdf0e10cSrcweir                             return NEW_NAME;
461cdf0e10cSrcweir                         }
462cdf0e10cSrcweir                         else
463cdf0e10cSrcweir                         {
464cdf0e10cSrcweir                             OSL_ENSURE( sal_False,
465cdf0e10cSrcweir                                         "Unknown interaction continuation!" );
466cdf0e10cSrcweir                             return UNKNOWN;
467cdf0e10cSrcweir                         }
468cdf0e10cSrcweir                     }
469cdf0e10cSrcweir                 }
470cdf0e10cSrcweir             }
471cdf0e10cSrcweir         }
472cdf0e10cSrcweir     }
473cdf0e10cSrcweir     return NOT_HANDLED;
474cdf0e10cSrcweir }
475cdf0e10cSrcweir 
476cdf0e10cSrcweir //=========================================================================
setTitle(const uno::Reference<ucb::XCommandProcessor> & xCommandProcessor,const uno::Reference<ucb::XCommandEnvironment> & xEnv,const rtl::OUString & rNewTitle)477cdf0e10cSrcweir bool setTitle(
478cdf0e10cSrcweir         const uno::Reference< ucb::XCommandProcessor > & xCommandProcessor,
479cdf0e10cSrcweir         const uno::Reference< ucb::XCommandEnvironment > & xEnv,
480cdf0e10cSrcweir         const rtl::OUString & rNewTitle )
481cdf0e10cSrcweir     throw( uno::RuntimeException )
482cdf0e10cSrcweir {
483cdf0e10cSrcweir     try
484cdf0e10cSrcweir     {
485cdf0e10cSrcweir         uno::Sequence< beans::PropertyValue > aPropValues( 1 );
486cdf0e10cSrcweir         aPropValues[ 0 ].Name
487cdf0e10cSrcweir             = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
488cdf0e10cSrcweir         aPropValues[ 0 ].Handle = -1;
489cdf0e10cSrcweir         aPropValues[ 0 ].Value  = uno::makeAny( rNewTitle );
490cdf0e10cSrcweir 
491cdf0e10cSrcweir         ucb::Command aSetPropsCommand(
492cdf0e10cSrcweir             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ),
493cdf0e10cSrcweir             -1,
494cdf0e10cSrcweir             uno::makeAny( aPropValues ) );
495cdf0e10cSrcweir 
496cdf0e10cSrcweir         uno::Any aResult
497cdf0e10cSrcweir             = xCommandProcessor->execute( aSetPropsCommand, 0, xEnv );
498cdf0e10cSrcweir 
499cdf0e10cSrcweir         uno::Sequence< uno::Any > aErrors;
500cdf0e10cSrcweir         aResult >>= aErrors;
501cdf0e10cSrcweir 
502cdf0e10cSrcweir         OSL_ENSURE( aErrors.getLength() == 1,
503cdf0e10cSrcweir                     "getPropertyValues return value invalid!" );
504cdf0e10cSrcweir 
505cdf0e10cSrcweir         if ( aErrors[ 0 ].hasValue() )
506cdf0e10cSrcweir         {
507*86e1cf34SPedro Giffuni             // error occurred.
508cdf0e10cSrcweir             OSL_ENSURE( sal_False, "error setting Title property!" );
509cdf0e10cSrcweir             return false;
510cdf0e10cSrcweir         }
511cdf0e10cSrcweir     }
512cdf0e10cSrcweir     catch ( uno::RuntimeException const & )
513cdf0e10cSrcweir     {
514cdf0e10cSrcweir         throw;
515cdf0e10cSrcweir     }
516cdf0e10cSrcweir     catch ( uno::Exception const & )
517cdf0e10cSrcweir     {
518cdf0e10cSrcweir         return false;
519cdf0e10cSrcweir     }
520cdf0e10cSrcweir 
521cdf0e10cSrcweir     return true;
522cdf0e10cSrcweir }
523cdf0e10cSrcweir 
524cdf0e10cSrcweir //=========================================================================
createNew(const TransferCommandContext & rContext,const uno::Reference<ucb::XContent> & xTarget,sal_Bool bSourceIsFolder,sal_Bool bSourceIsDocument,sal_Bool bSourceIsLink)525cdf0e10cSrcweir uno::Reference< ucb::XContent > createNew(
526cdf0e10cSrcweir                     const TransferCommandContext & rContext,
527cdf0e10cSrcweir                     const uno::Reference< ucb::XContent > & xTarget,
528cdf0e10cSrcweir                     sal_Bool bSourceIsFolder,
529cdf0e10cSrcweir                     sal_Bool bSourceIsDocument,
530cdf0e10cSrcweir                     sal_Bool bSourceIsLink )
531cdf0e10cSrcweir     throw( uno::Exception )
532cdf0e10cSrcweir {
533cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
534cdf0e10cSrcweir     //
535cdf0e10cSrcweir     // (1) Obtain creatable types from target.
536cdf0e10cSrcweir     //
537cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
538cdf0e10cSrcweir 
539cdf0e10cSrcweir     // First, try it using "CreatabeleContentsInfo" property and
540cdf0e10cSrcweir     // "createNewContent" command -> the "new" way.
541cdf0e10cSrcweir 
542cdf0e10cSrcweir     uno::Reference< ucb::XCommandProcessor > xCommandProcessorT(
543cdf0e10cSrcweir                                                     xTarget, uno::UNO_QUERY );
544cdf0e10cSrcweir     if ( !xCommandProcessorT.is() )
545cdf0e10cSrcweir     {
546cdf0e10cSrcweir         uno::Any aProps
547cdf0e10cSrcweir             = uno::makeAny(beans::PropertyValue(
548cdf0e10cSrcweir                                   rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
549cdf0e10cSrcweir                                                     "Folder")),
550cdf0e10cSrcweir                                   -1,
551cdf0e10cSrcweir                                   uno::makeAny(rContext.aArg.TargetURL),
552cdf0e10cSrcweir                                   beans::PropertyState_DIRECT_VALUE));
553cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
554cdf0e10cSrcweir             ucb::IOErrorCode_CANT_CREATE,
555cdf0e10cSrcweir             uno::Sequence< uno::Any >(&aProps, 1),
556cdf0e10cSrcweir             rContext.xOrigEnv,
557cdf0e10cSrcweir             rtl::OUString::createFromAscii( "Target is no XCommandProcessor!" ),
558cdf0e10cSrcweir             rContext.xProcessor );
559cdf0e10cSrcweir         // Unreachable
560cdf0e10cSrcweir     }
561cdf0e10cSrcweir 
562cdf0e10cSrcweir     uno::Sequence< beans::Property > aPropsToObtain( 1 );
563cdf0e10cSrcweir     aPropsToObtain[ 0 ].Name
564cdf0e10cSrcweir         = rtl::OUString::createFromAscii( "CreatableContentsInfo" );
565cdf0e10cSrcweir     aPropsToObtain[ 0 ].Handle
566cdf0e10cSrcweir         = -1;
567cdf0e10cSrcweir 
568cdf0e10cSrcweir     ucb::Command aGetPropsCommand(
569cdf0e10cSrcweir             rtl::OUString::createFromAscii( "getPropertyValues" ),
570cdf0e10cSrcweir             -1,
571cdf0e10cSrcweir             uno::makeAny( aPropsToObtain ) );
572cdf0e10cSrcweir 
573cdf0e10cSrcweir     uno::Reference< sdbc::XRow > xRow;
574cdf0e10cSrcweir     xCommandProcessorT->execute( aGetPropsCommand, 0, rContext.xEnv )  >>= xRow;
575cdf0e10cSrcweir 
576cdf0e10cSrcweir     uno::Sequence< ucb::ContentInfo > aTypesInfo;
577cdf0e10cSrcweir     bool bGotTypesInfo = false;
578cdf0e10cSrcweir 
579cdf0e10cSrcweir     if ( xRow.is() )
580cdf0e10cSrcweir     {
581cdf0e10cSrcweir         uno::Any  aValue = xRow->getObject(
582cdf0e10cSrcweir             1, uno::Reference< container::XNameAccess >() );
583cdf0e10cSrcweir         if ( aValue.hasValue() && ( aValue >>= aTypesInfo ) )
584cdf0e10cSrcweir         {
585cdf0e10cSrcweir             bGotTypesInfo = true;
586cdf0e10cSrcweir         }
587cdf0e10cSrcweir     }
588cdf0e10cSrcweir 
589cdf0e10cSrcweir     uno::Reference< ucb::XContentCreator > xCreator;
590cdf0e10cSrcweir 
591cdf0e10cSrcweir     if ( !bGotTypesInfo )
592cdf0e10cSrcweir     {
593cdf0e10cSrcweir         // Second, try it using XContentCreator interface -> the "old" way (not
594cdf0e10cSrcweir         // providing the chance to supply an XCommandEnvironment.
595cdf0e10cSrcweir 
596cdf0e10cSrcweir         xCreator.set( xTarget, uno::UNO_QUERY );
597cdf0e10cSrcweir 
598cdf0e10cSrcweir         if ( !xCreator.is() )
599cdf0e10cSrcweir         {
600cdf0e10cSrcweir             uno::Any aProps
601cdf0e10cSrcweir                 = uno::makeAny(beans::PropertyValue(
602cdf0e10cSrcweir                                   rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
603cdf0e10cSrcweir                                                     "Folder")),
604cdf0e10cSrcweir                                   -1,
605cdf0e10cSrcweir                                   uno::makeAny(rContext.aArg.TargetURL),
606cdf0e10cSrcweir                                   beans::PropertyState_DIRECT_VALUE));
607cdf0e10cSrcweir             ucbhelper::cancelCommandExecution(
608cdf0e10cSrcweir                 ucb::IOErrorCode_CANT_CREATE,
609cdf0e10cSrcweir                 uno::Sequence< uno::Any >(&aProps, 1),
610cdf0e10cSrcweir                 rContext.xOrigEnv,
611cdf0e10cSrcweir                 rtl::OUString::createFromAscii( "Target is no XContentCreator!" ),
612cdf0e10cSrcweir                 rContext.xProcessor );
613cdf0e10cSrcweir             // Unreachable
614cdf0e10cSrcweir         }
615cdf0e10cSrcweir 
616cdf0e10cSrcweir         aTypesInfo  = xCreator->queryCreatableContentsInfo();
617cdf0e10cSrcweir     }
618cdf0e10cSrcweir 
619cdf0e10cSrcweir     sal_Int32 nCount = aTypesInfo.getLength();
620cdf0e10cSrcweir     if ( !nCount )
621cdf0e10cSrcweir     {
622cdf0e10cSrcweir         uno::Any aProps
623cdf0e10cSrcweir             = uno::makeAny(beans::PropertyValue(
624cdf0e10cSrcweir                               rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Folder")),
625cdf0e10cSrcweir                               -1,
626cdf0e10cSrcweir                               uno::makeAny(rContext.aArg.TargetURL),
627cdf0e10cSrcweir                               beans::PropertyState_DIRECT_VALUE));
628cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
629cdf0e10cSrcweir             ucb::IOErrorCode_CANT_CREATE,
630cdf0e10cSrcweir             uno::Sequence< uno::Any >(&aProps, 1),
631cdf0e10cSrcweir             rContext.xOrigEnv,
632cdf0e10cSrcweir             rtl::OUString::createFromAscii( "No types creatable!" ),
633cdf0e10cSrcweir             rContext.xProcessor );
634cdf0e10cSrcweir         // Unreachable
635cdf0e10cSrcweir     }
636cdf0e10cSrcweir 
637cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
638cdf0e10cSrcweir     //
639cdf0e10cSrcweir     // (2) Try to find a matching target type for the source object.
640cdf0e10cSrcweir     //
641cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
642cdf0e10cSrcweir 
643cdf0e10cSrcweir     uno::Reference< ucb::XContent > xNew;
644cdf0e10cSrcweir     for ( sal_Int32 n = 0; n < nCount; ++n )
645cdf0e10cSrcweir     {
646cdf0e10cSrcweir         sal_Int32 nAttribs = aTypesInfo[ n ].Attributes;
647cdf0e10cSrcweir         sal_Bool  bMatch   = sal_False;
648cdf0e10cSrcweir 
649cdf0e10cSrcweir         if ( rContext.aArg.Operation == ucb::TransferCommandOperation_LINK )
650cdf0e10cSrcweir         {
651cdf0e10cSrcweir             // Create link
652cdf0e10cSrcweir 
653cdf0e10cSrcweir             if ( nAttribs & ucb::ContentInfoAttribute::KIND_LINK )
654cdf0e10cSrcweir             {
655cdf0e10cSrcweir                 // Match!
656cdf0e10cSrcweir                 bMatch = sal_True;
657cdf0e10cSrcweir             }
658cdf0e10cSrcweir         }
659cdf0e10cSrcweir         else if ( ( rContext.aArg.Operation
660cdf0e10cSrcweir                         == ucb::TransferCommandOperation_COPY ) ||
661cdf0e10cSrcweir                   ( rContext.aArg.Operation
662cdf0e10cSrcweir                         == ucb::TransferCommandOperation_MOVE ) )
663cdf0e10cSrcweir         {
664cdf0e10cSrcweir             // Copy / Move
665cdf0e10cSrcweir 
666cdf0e10cSrcweir             // Is source a link? Create link in target folder then.
667cdf0e10cSrcweir             if ( bSourceIsLink )
668cdf0e10cSrcweir             {
669cdf0e10cSrcweir                 if ( nAttribs & ucb::ContentInfoAttribute::KIND_LINK )
670cdf0e10cSrcweir                 {
671cdf0e10cSrcweir                     // Match!
672cdf0e10cSrcweir                     bMatch = sal_True;
673cdf0e10cSrcweir                 }
674cdf0e10cSrcweir             }
675cdf0e10cSrcweir             else
676cdf0e10cSrcweir             {
677cdf0e10cSrcweir                 // (not a and not b) or (a and b)
678cdf0e10cSrcweir                 // not( a or b) or (a and b)
679cdf0e10cSrcweir                 //
680cdf0e10cSrcweir                 if ( ( !!bSourceIsFolder ==
681cdf0e10cSrcweir                         !!( nAttribs
682cdf0e10cSrcweir                             & ucb::ContentInfoAttribute::KIND_FOLDER ) )
683cdf0e10cSrcweir                      &&
684cdf0e10cSrcweir                      ( !!bSourceIsDocument ==
685cdf0e10cSrcweir                         !!( nAttribs
686cdf0e10cSrcweir                             & ucb::ContentInfoAttribute::KIND_DOCUMENT ) )
687cdf0e10cSrcweir                    )
688cdf0e10cSrcweir                 {
689cdf0e10cSrcweir                     // Match!
690cdf0e10cSrcweir                     bMatch = sal_True;
691cdf0e10cSrcweir                 }
692cdf0e10cSrcweir             }
693cdf0e10cSrcweir         }
694cdf0e10cSrcweir         else
695cdf0e10cSrcweir         {
696cdf0e10cSrcweir             ucbhelper::cancelCommandExecution(
697cdf0e10cSrcweir                 uno::makeAny( lang::IllegalArgumentException(
698cdf0e10cSrcweir                                         rtl::OUString::createFromAscii(
699cdf0e10cSrcweir                                             "Unknown transfer operation!" ),
700cdf0e10cSrcweir                                         rContext.xProcessor,
701cdf0e10cSrcweir                                         -1 ) ),
702cdf0e10cSrcweir                               rContext.xOrigEnv );
703cdf0e10cSrcweir             // Unreachable
704cdf0e10cSrcweir         }
705cdf0e10cSrcweir 
706cdf0e10cSrcweir         if ( bMatch )
707cdf0e10cSrcweir         {
708cdf0e10cSrcweir             //////////////////////////////////////////////////////////////
709cdf0e10cSrcweir             //
710cdf0e10cSrcweir             // (3) Create a new, empty object of matched type.
711cdf0e10cSrcweir             //
712cdf0e10cSrcweir             //////////////////////////////////////////////////////////////
713cdf0e10cSrcweir 
714cdf0e10cSrcweir             if ( !xCreator.is() )
715cdf0e10cSrcweir             {
716cdf0e10cSrcweir                 // First, try it using "CreatabeleContentsInfo" property and
717cdf0e10cSrcweir                 // "createNewContent" command -> the "new" way.
718cdf0e10cSrcweir                 ucb::Command aCreateNewCommand(
719cdf0e10cSrcweir                    rtl::OUString::createFromAscii( "createNewContent" ),
720cdf0e10cSrcweir                    -1,
721cdf0e10cSrcweir                    uno::makeAny( aTypesInfo[ n ] ) );
722cdf0e10cSrcweir 
723cdf0e10cSrcweir                 xCommandProcessorT->execute( aCreateNewCommand, 0, rContext.xEnv )
724cdf0e10cSrcweir                     >>= xNew;
725cdf0e10cSrcweir             }
726cdf0e10cSrcweir             else
727cdf0e10cSrcweir             {
728cdf0e10cSrcweir                 // Second, try it using XContentCreator interface -> the "old"
729cdf0e10cSrcweir                 // way (not providing the chance to supply an XCommandEnvironment.
730cdf0e10cSrcweir 
731cdf0e10cSrcweir                 xNew = xCreator->createNewContent( aTypesInfo[ n ] );
732cdf0e10cSrcweir             }
733cdf0e10cSrcweir 
734cdf0e10cSrcweir             if ( !xNew.is() )
735cdf0e10cSrcweir             {
736cdf0e10cSrcweir                 uno::Any aProps
737cdf0e10cSrcweir                     = uno::makeAny(
738cdf0e10cSrcweir                              beans::PropertyValue(
739cdf0e10cSrcweir                                  rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
740cdf0e10cSrcweir                                                    "Folder")),
741cdf0e10cSrcweir                                  -1,
742cdf0e10cSrcweir                                  uno::makeAny(rContext.aArg.TargetURL),
743cdf0e10cSrcweir                                  beans::PropertyState_DIRECT_VALUE));
744cdf0e10cSrcweir                 ucbhelper::cancelCommandExecution(
745cdf0e10cSrcweir                     ucb::IOErrorCode_CANT_CREATE,
746cdf0e10cSrcweir                     uno::Sequence< uno::Any >(&aProps, 1),
747cdf0e10cSrcweir                     rContext.xOrigEnv,
748cdf0e10cSrcweir                     rtl::OUString::createFromAscii(
749cdf0e10cSrcweir                         "createNewContent failed!" ),
750cdf0e10cSrcweir                     rContext.xProcessor );
751cdf0e10cSrcweir                 // Unreachable
752cdf0e10cSrcweir             }
753cdf0e10cSrcweir             break; // escape from 'for' loop
754cdf0e10cSrcweir         }
755cdf0e10cSrcweir     } // for
756cdf0e10cSrcweir 
757cdf0e10cSrcweir     return xNew;
758cdf0e10cSrcweir }
759cdf0e10cSrcweir 
760cdf0e10cSrcweir //=========================================================================
transferProperties(const TransferCommandContext & rContext,const uno::Reference<ucb::XCommandProcessor> & xCommandProcessorS,const uno::Reference<ucb::XCommandProcessor> & xCommandProcessorN)761cdf0e10cSrcweir void transferProperties(
762cdf0e10cSrcweir     const TransferCommandContext & rContext,
763cdf0e10cSrcweir     const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorS,
764cdf0e10cSrcweir     const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorN )
765cdf0e10cSrcweir         throw( uno::Exception )
766cdf0e10cSrcweir {
767cdf0e10cSrcweir     ucb::Command aGetPropertySetInfoCommand(
768cdf0e10cSrcweir                 rtl::OUString::createFromAscii( "getPropertySetInfo" ),
769cdf0e10cSrcweir                 -1,
770cdf0e10cSrcweir                 uno::Any() );
771cdf0e10cSrcweir 
772cdf0e10cSrcweir     uno::Reference< beans::XPropertySetInfo > xInfo;
773cdf0e10cSrcweir     xCommandProcessorS->execute( aGetPropertySetInfoCommand, 0, rContext.xEnv )
774cdf0e10cSrcweir         >>= xInfo;
775cdf0e10cSrcweir 
776cdf0e10cSrcweir     if ( !xInfo.is() )
777cdf0e10cSrcweir     {
778cdf0e10cSrcweir         uno::Any aProps
779cdf0e10cSrcweir             = uno::makeAny(beans::PropertyValue(
780cdf0e10cSrcweir                                   rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
781cdf0e10cSrcweir                                                     "Uri")),
782cdf0e10cSrcweir                                   -1,
783cdf0e10cSrcweir                                   uno::makeAny(rContext.aArg.SourceURL),
784cdf0e10cSrcweir                                   beans::PropertyState_DIRECT_VALUE));
785cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
786cdf0e10cSrcweir             ucb::IOErrorCode_CANT_READ,
787cdf0e10cSrcweir             uno::Sequence< uno::Any >(&aProps, 1),
788cdf0e10cSrcweir             rContext.xOrigEnv,
789cdf0e10cSrcweir             rtl::OUString::createFromAscii(
790cdf0e10cSrcweir                 "Unable to get propertyset info from source object!" ),
791cdf0e10cSrcweir             rContext.xProcessor );
792cdf0e10cSrcweir         // Unreachable
793cdf0e10cSrcweir     }
794cdf0e10cSrcweir 
795cdf0e10cSrcweir     uno::Sequence< beans::Property > aAllProps = xInfo->getProperties();
796cdf0e10cSrcweir 
797cdf0e10cSrcweir     ucb::Command aGetPropsCommand1(
798cdf0e10cSrcweir                 rtl::OUString::createFromAscii( "getPropertyValues" ),
799cdf0e10cSrcweir                 -1,
800cdf0e10cSrcweir                 uno::makeAny( aAllProps ) );
801cdf0e10cSrcweir 
802cdf0e10cSrcweir     uno::Reference< sdbc::XRow > xRow1;
803cdf0e10cSrcweir     xCommandProcessorS->execute(
804cdf0e10cSrcweir         aGetPropsCommand1, 0, rContext.xEnv ) >>= xRow1;
805cdf0e10cSrcweir 
806cdf0e10cSrcweir     if ( !xRow1.is() )
807cdf0e10cSrcweir     {
808cdf0e10cSrcweir         uno::Any aProps
809cdf0e10cSrcweir             = uno::makeAny(beans::PropertyValue(
810cdf0e10cSrcweir                                   rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
811cdf0e10cSrcweir                                                     "Uri")),
812cdf0e10cSrcweir                                   -1,
813cdf0e10cSrcweir                                   uno::makeAny(rContext.aArg.SourceURL),
814cdf0e10cSrcweir                                   beans::PropertyState_DIRECT_VALUE));
815cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
816cdf0e10cSrcweir             ucb::IOErrorCode_CANT_READ,
817cdf0e10cSrcweir             uno::Sequence< uno::Any >(&aProps, 1),
818cdf0e10cSrcweir             rContext.xOrigEnv,
819cdf0e10cSrcweir             rtl::OUString::createFromAscii(
820cdf0e10cSrcweir                 "Unable to get properties from source object!" ),
821cdf0e10cSrcweir             rContext.xProcessor );
822cdf0e10cSrcweir         // Unreachable
823cdf0e10cSrcweir     }
824cdf0e10cSrcweir 
825cdf0e10cSrcweir     // Assemble data structure for setPropertyValues command.
826cdf0e10cSrcweir 
827cdf0e10cSrcweir     // Note: Make room for additional Title and TargetURL too. -> + 2
828cdf0e10cSrcweir     uno::Sequence< beans::PropertyValue > aPropValues(
829cdf0e10cSrcweir                                                 aAllProps.getLength() + 2 );
830cdf0e10cSrcweir 
831cdf0e10cSrcweir     sal_Bool bHasTitle = ( rContext.aArg.NewTitle.getLength() == 0 );
832cdf0e10cSrcweir     sal_Bool bHasTargetURL = ( rContext.aArg.Operation
833cdf0e10cSrcweir                                 != ucb::TransferCommandOperation_LINK );
834cdf0e10cSrcweir 
835cdf0e10cSrcweir     sal_Int32 nWritePos = 0;
836cdf0e10cSrcweir     for ( sal_Int32 m = 0; m < aAllProps.getLength(); ++m )
837cdf0e10cSrcweir     {
838cdf0e10cSrcweir         const beans::Property & rCurrProp = aAllProps[ m ];
839cdf0e10cSrcweir         beans::PropertyValue & rCurrValue = aPropValues[ nWritePos ];
840cdf0e10cSrcweir 
841cdf0e10cSrcweir         uno::Any aValue;
842cdf0e10cSrcweir 
843cdf0e10cSrcweir         if ( rCurrProp.Name.compareToAscii( "Title" ) == 0 )
844cdf0e10cSrcweir         {
845cdf0e10cSrcweir             // Supply new title, if given.
846cdf0e10cSrcweir             if ( !bHasTitle )
847cdf0e10cSrcweir             {
848cdf0e10cSrcweir                 bHasTitle = sal_True;
849cdf0e10cSrcweir                 aValue <<= rContext.aArg.NewTitle;
850cdf0e10cSrcweir             }
851cdf0e10cSrcweir         }
852cdf0e10cSrcweir         else if ( rCurrProp.Name.compareToAscii( "TargetURL" ) == 0 )
853cdf0e10cSrcweir         {
854cdf0e10cSrcweir             // Supply source URL as link target for the new link to create.
855cdf0e10cSrcweir             if ( !bHasTargetURL )
856cdf0e10cSrcweir             {
857cdf0e10cSrcweir                 bHasTargetURL = sal_True;
858cdf0e10cSrcweir                 aValue <<= rContext.aArg.SourceURL;
859cdf0e10cSrcweir             }
860cdf0e10cSrcweir         }
861cdf0e10cSrcweir 
862cdf0e10cSrcweir         if ( !aValue.hasValue() )
863cdf0e10cSrcweir         {
864cdf0e10cSrcweir             try
865cdf0e10cSrcweir             {
866cdf0e10cSrcweir                 aValue = xRow1->getObject(
867cdf0e10cSrcweir                             m + 1, uno::Reference< container::XNameAccess >() );
868cdf0e10cSrcweir             }
869cdf0e10cSrcweir             catch ( sdbc::SQLException const & )
870cdf0e10cSrcweir             {
871cdf0e10cSrcweir                 // Argh! But try to bring things to an end. Perhaps the
872cdf0e10cSrcweir                 // mad property is not really important...
873cdf0e10cSrcweir             }
874cdf0e10cSrcweir         }
875cdf0e10cSrcweir 
876cdf0e10cSrcweir         if ( aValue.hasValue() )
877cdf0e10cSrcweir         {
878cdf0e10cSrcweir             rCurrValue.Name   = rCurrProp.Name;
879cdf0e10cSrcweir             rCurrValue.Handle = rCurrProp.Handle;
880cdf0e10cSrcweir             rCurrValue.Value  = aValue;
881cdf0e10cSrcweir //          rCurrValue.State  =
882cdf0e10cSrcweir 
883cdf0e10cSrcweir             nWritePos++;
884cdf0e10cSrcweir         }
885cdf0e10cSrcweir     }
886cdf0e10cSrcweir 
887cdf0e10cSrcweir     // Title needed, but not set yet?
888cdf0e10cSrcweir     if ( !bHasTitle && ( rContext.aArg.NewTitle.getLength() > 0 ) )
889cdf0e10cSrcweir     {
890cdf0e10cSrcweir         aPropValues[ nWritePos ].Name
891cdf0e10cSrcweir             = rtl::OUString::createFromAscii( "Title" );
892cdf0e10cSrcweir         aPropValues[ nWritePos ].Handle = -1;
893cdf0e10cSrcweir         aPropValues[ nWritePos ].Value <<= rContext.aArg.NewTitle;
894cdf0e10cSrcweir 
895cdf0e10cSrcweir         nWritePos++;
896cdf0e10cSrcweir     }
897cdf0e10cSrcweir 
898cdf0e10cSrcweir     // TargetURL needed, but not set yet?
899cdf0e10cSrcweir     if ( !bHasTargetURL && ( rContext.aArg.Operation
900cdf0e10cSrcweir                                 == ucb::TransferCommandOperation_LINK ) )
901cdf0e10cSrcweir     {
902cdf0e10cSrcweir         aPropValues[ nWritePos ].Name
903cdf0e10cSrcweir             = rtl::OUString::createFromAscii( "TargetURL" );
904cdf0e10cSrcweir         aPropValues[ nWritePos ].Handle = -1;
905cdf0e10cSrcweir         aPropValues[ nWritePos ].Value <<= rContext.aArg.SourceURL;
906cdf0e10cSrcweir 
907cdf0e10cSrcweir         nWritePos++;
908cdf0e10cSrcweir     }
909cdf0e10cSrcweir 
910cdf0e10cSrcweir     aPropValues.realloc( nWritePos );
911cdf0e10cSrcweir 
912cdf0e10cSrcweir     // Set properties at new object.
913cdf0e10cSrcweir 
914cdf0e10cSrcweir     ucb::Command aSetPropsCommand(
915cdf0e10cSrcweir                 rtl::OUString::createFromAscii( "setPropertyValues" ),
916cdf0e10cSrcweir                 -1,
917cdf0e10cSrcweir                 uno::makeAny( aPropValues ) );
918cdf0e10cSrcweir 
919cdf0e10cSrcweir     xCommandProcessorN->execute( aSetPropsCommand, 0, rContext.xEnv );
920cdf0e10cSrcweir 
921cdf0e10cSrcweir     // @@@ What to do with source props that are not supported by the
922cdf0e10cSrcweir     //     new object? addProperty ???
923cdf0e10cSrcweir }
924cdf0e10cSrcweir 
925cdf0e10cSrcweir //=========================================================================
getInputStream(const TransferCommandContext & rContext,const uno::Reference<ucb::XCommandProcessor> & xCommandProcessorS)926cdf0e10cSrcweir uno::Reference< io::XInputStream > getInputStream(
927cdf0e10cSrcweir     const TransferCommandContext & rContext,
928cdf0e10cSrcweir     const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorS )
929cdf0e10cSrcweir         throw( uno::Exception )
930cdf0e10cSrcweir {
931cdf0e10cSrcweir     uno::Reference< io::XInputStream > xInputStream;
932cdf0e10cSrcweir 
933cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
934cdf0e10cSrcweir     //
935cdf0e10cSrcweir     // (1) Try to get data as XInputStream via XActiveDataSink.
936cdf0e10cSrcweir     //
937cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
938cdf0e10cSrcweir 
939cdf0e10cSrcweir     try
940cdf0e10cSrcweir     {
941cdf0e10cSrcweir         uno::Reference< io::XActiveDataSink > xSink = new ActiveDataSink;
942cdf0e10cSrcweir 
943cdf0e10cSrcweir         ucb::OpenCommandArgument2 aArg;
944cdf0e10cSrcweir         aArg.Mode       = ucb::OpenMode::DOCUMENT;
945cdf0e10cSrcweir         aArg.Priority   = 0; // unused
946cdf0e10cSrcweir         aArg.Sink       = xSink;
947cdf0e10cSrcweir         aArg.Properties = uno::Sequence< beans::Property >( 0 ); // unused
948cdf0e10cSrcweir 
949cdf0e10cSrcweir         ucb::Command aOpenCommand(
950cdf0e10cSrcweir                                 rtl::OUString::createFromAscii( "open" ),
951cdf0e10cSrcweir                                 -1,
952cdf0e10cSrcweir                                 uno::makeAny( aArg ) );
953cdf0e10cSrcweir 
954cdf0e10cSrcweir         xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv );
955cdf0e10cSrcweir         xInputStream = xSink->getInputStream();
956cdf0e10cSrcweir     }
957cdf0e10cSrcweir     catch ( uno::RuntimeException const & )
958cdf0e10cSrcweir     {
959cdf0e10cSrcweir         throw;
960cdf0e10cSrcweir     }
961cdf0e10cSrcweir     catch ( uno::Exception const & )
962cdf0e10cSrcweir     {
963cdf0e10cSrcweir         // will be handled below.
964cdf0e10cSrcweir     }
965cdf0e10cSrcweir 
966cdf0e10cSrcweir     if ( !xInputStream.is() )
967cdf0e10cSrcweir     {
968cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
969cdf0e10cSrcweir         //
970cdf0e10cSrcweir         // (2) Try to get data via XOutputStream.
971cdf0e10cSrcweir         //
972cdf0e10cSrcweir         //////////////////////////////////////////////////////////////////
973cdf0e10cSrcweir 
974cdf0e10cSrcweir         try
975cdf0e10cSrcweir         {
976cdf0e10cSrcweir             uno::Reference< io::XOutputStream > xOutputStream(
977cdf0e10cSrcweir                 rContext.xSMgr->createInstance(
978cdf0e10cSrcweir                     rtl::OUString::createFromAscii( "com.sun.star.io.Pipe" ) ),
979cdf0e10cSrcweir                 uno::UNO_QUERY );
980cdf0e10cSrcweir 
981cdf0e10cSrcweir             if ( xOutputStream.is() )
982cdf0e10cSrcweir             {
983cdf0e10cSrcweir                 ucb::OpenCommandArgument2 aArg;
984cdf0e10cSrcweir                 aArg.Mode       = ucb::OpenMode::DOCUMENT;
985cdf0e10cSrcweir                 aArg.Priority   = 0; // unused
986cdf0e10cSrcweir                 aArg.Sink       = xOutputStream;
987cdf0e10cSrcweir                 aArg.Properties = uno::Sequence< beans::Property >( 0 );
988cdf0e10cSrcweir 
989cdf0e10cSrcweir                 ucb::Command aOpenCommand(
990cdf0e10cSrcweir                                     rtl::OUString::createFromAscii( "open" ),
991cdf0e10cSrcweir                                     -1,
992cdf0e10cSrcweir                                     uno::makeAny( aArg ) );
993cdf0e10cSrcweir 
994cdf0e10cSrcweir                 xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv );
995cdf0e10cSrcweir 
996cdf0e10cSrcweir                 xInputStream = uno::Reference< io::XInputStream >(
997cdf0e10cSrcweir                                         xOutputStream, uno::UNO_QUERY );
998cdf0e10cSrcweir             }
999cdf0e10cSrcweir         }
1000cdf0e10cSrcweir         catch ( uno::RuntimeException const & )
1001cdf0e10cSrcweir         {
1002cdf0e10cSrcweir             throw;
1003cdf0e10cSrcweir         }
1004cdf0e10cSrcweir         catch ( uno::Exception const & )
1005cdf0e10cSrcweir         {
1006cdf0e10cSrcweir             OSL_ENSURE( sal_False, "unable to get input stream from document!" );
1007cdf0e10cSrcweir         }
1008cdf0e10cSrcweir     }
1009cdf0e10cSrcweir 
1010cdf0e10cSrcweir     return xInputStream;
1011cdf0e10cSrcweir }
1012cdf0e10cSrcweir 
1013cdf0e10cSrcweir //=========================================================================
getResultSet(const TransferCommandContext & rContext,const uno::Reference<ucb::XCommandProcessor> & xCommandProcessorS)1014cdf0e10cSrcweir uno::Reference< sdbc::XResultSet > getResultSet(
1015cdf0e10cSrcweir     const TransferCommandContext & rContext,
1016cdf0e10cSrcweir     const uno::Reference< ucb::XCommandProcessor > & xCommandProcessorS )
1017cdf0e10cSrcweir         throw( uno::Exception )
1018cdf0e10cSrcweir {
1019cdf0e10cSrcweir     uno::Reference< sdbc::XResultSet > xResultSet;
1020cdf0e10cSrcweir 
1021cdf0e10cSrcweir     uno::Sequence< beans::Property > aProps( 3 );
1022cdf0e10cSrcweir 
1023cdf0e10cSrcweir     aProps[ 0 ].Name   = rtl::OUString::createFromAscii( "IsFolder" );
1024cdf0e10cSrcweir     aProps[ 0 ].Handle = -1; /* unknown */
1025cdf0e10cSrcweir     aProps[ 1 ].Name   = rtl::OUString::createFromAscii( "IsDocument" );
1026cdf0e10cSrcweir     aProps[ 1 ].Handle = -1; /* unknown */
1027cdf0e10cSrcweir     aProps[ 2 ].Name   = rtl::OUString::createFromAscii( "TargetURL" );
1028cdf0e10cSrcweir     aProps[ 2 ].Handle = -1; /* unknown */
1029cdf0e10cSrcweir 
1030cdf0e10cSrcweir     ucb::OpenCommandArgument2 aArg;
1031cdf0e10cSrcweir     aArg.Mode       = ucb::OpenMode::ALL;
1032cdf0e10cSrcweir     aArg.Priority   = 0; // unused
1033cdf0e10cSrcweir     aArg.Sink       = 0;
1034cdf0e10cSrcweir     aArg.Properties = aProps;
1035cdf0e10cSrcweir 
1036cdf0e10cSrcweir     ucb::Command aOpenCommand( rtl::OUString::createFromAscii( "open" ),
1037cdf0e10cSrcweir                                      -1,
1038cdf0e10cSrcweir                                      uno::makeAny( aArg ) );
1039cdf0e10cSrcweir     try
1040cdf0e10cSrcweir     {
1041cdf0e10cSrcweir         uno::Reference< ucb::XDynamicResultSet > xSet;
1042cdf0e10cSrcweir         xCommandProcessorS->execute( aOpenCommand, 0, rContext.xEnv ) >>= xSet;
1043cdf0e10cSrcweir 
1044cdf0e10cSrcweir         if ( xSet.is() )
1045cdf0e10cSrcweir             xResultSet = xSet->getStaticResultSet();
1046cdf0e10cSrcweir     }
1047cdf0e10cSrcweir     catch ( uno::RuntimeException const & )
1048cdf0e10cSrcweir     {
1049cdf0e10cSrcweir         throw;
1050cdf0e10cSrcweir     }
1051cdf0e10cSrcweir     catch ( uno::Exception const & )
1052cdf0e10cSrcweir     {
1053cdf0e10cSrcweir          OSL_ENSURE( sal_False, "unable to get result set from folder!" );
1054cdf0e10cSrcweir     }
1055cdf0e10cSrcweir 
1056cdf0e10cSrcweir     return xResultSet;
1057cdf0e10cSrcweir }
1058cdf0e10cSrcweir 
1059cdf0e10cSrcweir //=========================================================================
handleNameClashRename(const TransferCommandContext & rContext,const uno::Reference<ucb::XContent> & xNew,const uno::Reference<ucb::XCommandProcessor> & xCommandProcessorN,const uno::Reference<ucb::XCommandProcessor> & xCommandProcessorS,uno::Reference<io::XInputStream> & xInputStream)1060cdf0e10cSrcweir void handleNameClashRename(
1061cdf0e10cSrcweir         const TransferCommandContext & rContext,
1062cdf0e10cSrcweir         const uno::Reference< ucb::XContent > & xNew,
1063cdf0e10cSrcweir         const uno::Reference<
1064cdf0e10cSrcweir             ucb::XCommandProcessor > & xCommandProcessorN,
1065cdf0e10cSrcweir         const uno::Reference<
1066cdf0e10cSrcweir             ucb::XCommandProcessor > & xCommandProcessorS,
1067cdf0e10cSrcweir         /* [inout] */ uno::Reference< io::XInputStream > & xInputStream )
1068cdf0e10cSrcweir     throw( uno::Exception )
1069cdf0e10cSrcweir {
1070cdf0e10cSrcweir     sal_Int32 nTry = 0;
1071cdf0e10cSrcweir 
1072cdf0e10cSrcweir     // Obtain old title.
1073cdf0e10cSrcweir     uno::Sequence< beans::Property > aProps( 1 );
1074cdf0e10cSrcweir     aProps[ 0 ].Name   = rtl::OUString::createFromAscii( "Title" );
1075cdf0e10cSrcweir     aProps[ 0 ].Handle = -1;
1076cdf0e10cSrcweir 
1077cdf0e10cSrcweir     ucb::Command aGetPropsCommand(
1078cdf0e10cSrcweir             rtl::OUString::createFromAscii( "getPropertyValues" ),
1079cdf0e10cSrcweir             -1,
1080cdf0e10cSrcweir             uno::makeAny( aProps ) );
1081cdf0e10cSrcweir 
1082cdf0e10cSrcweir     uno::Reference< sdbc::XRow > xRow;
1083cdf0e10cSrcweir     xCommandProcessorN->execute( aGetPropsCommand, 0, rContext.xEnv )  >>= xRow;
1084cdf0e10cSrcweir 
1085cdf0e10cSrcweir     if ( !xRow.is() )
1086cdf0e10cSrcweir     {
1087cdf0e10cSrcweir         uno::Any aProps2
1088cdf0e10cSrcweir             = uno::makeAny(
1089cdf0e10cSrcweir                      beans::PropertyValue(
1090cdf0e10cSrcweir                          rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Uri" ) ),
1091cdf0e10cSrcweir                          -1,
1092cdf0e10cSrcweir                          uno::makeAny(
1093cdf0e10cSrcweir                              xNew->getIdentifier()->getContentIdentifier() ),
1094cdf0e10cSrcweir                          beans::PropertyState_DIRECT_VALUE ) );
1095cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
1096cdf0e10cSrcweir             ucb::IOErrorCode_CANT_READ,
1097cdf0e10cSrcweir             uno::Sequence< uno::Any >( &aProps2, 1 ),
1098cdf0e10cSrcweir             rContext.xOrigEnv,
1099cdf0e10cSrcweir             rtl::OUString::createFromAscii(
1100cdf0e10cSrcweir                 "Unable to get properties from new object!" ),
1101cdf0e10cSrcweir             rContext.xProcessor );
1102cdf0e10cSrcweir         // Unreachable
1103cdf0e10cSrcweir     }
1104cdf0e10cSrcweir 
1105cdf0e10cSrcweir     rtl::OUString aOldTitle = xRow->getString( 1 );
1106cdf0e10cSrcweir     if ( !aOldTitle.getLength() )
1107cdf0e10cSrcweir     {
1108cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
1109cdf0e10cSrcweir             uno::makeAny( beans::UnknownPropertyException(
1110cdf0e10cSrcweir                             rtl::OUString::createFromAscii(
1111cdf0e10cSrcweir                                 "Unable to get property 'Title' "
1112cdf0e10cSrcweir                                 "from new object!" ),
1113cdf0e10cSrcweir                             rContext.xProcessor ) ),
1114cdf0e10cSrcweir             rContext.xOrigEnv );
1115cdf0e10cSrcweir         // Unreachable
1116cdf0e10cSrcweir     }
1117cdf0e10cSrcweir 
1118cdf0e10cSrcweir     // Some pseudo-intelligence for not destroying file extensions.
1119cdf0e10cSrcweir     rtl::OUString aOldTitlePre;
1120cdf0e10cSrcweir     rtl::OUString aOldTitlePost;
1121cdf0e10cSrcweir     sal_Int32 nPos = aOldTitle.lastIndexOf( '.' );
1122cdf0e10cSrcweir     if ( nPos != -1 )
1123cdf0e10cSrcweir     {
1124cdf0e10cSrcweir         aOldTitlePre = aOldTitle.copy( 0, nPos );
1125cdf0e10cSrcweir         aOldTitlePost = aOldTitle.copy( nPos );
1126cdf0e10cSrcweir     }
1127cdf0e10cSrcweir     else
1128cdf0e10cSrcweir         aOldTitlePre = aOldTitle;
1129cdf0e10cSrcweir 
1130cdf0e10cSrcweir     if ( nPos > 0 )
1131cdf0e10cSrcweir         aOldTitlePre += rtl::OUString::createFromAscii( "_" );
1132cdf0e10cSrcweir 
1133cdf0e10cSrcweir     sal_Bool bContinue = sal_True;
1134cdf0e10cSrcweir     do
1135cdf0e10cSrcweir     {
1136cdf0e10cSrcweir         nTry++;
1137cdf0e10cSrcweir 
1138cdf0e10cSrcweir         rtl::OUString aNewTitle = aOldTitlePre;
1139cdf0e10cSrcweir         aNewTitle += rtl::OUString::valueOf( nTry );
1140cdf0e10cSrcweir         aNewTitle += aOldTitlePost;
1141cdf0e10cSrcweir 
1142cdf0e10cSrcweir         // Set new title
1143cdf0e10cSrcweir         setTitle( xCommandProcessorN, rContext.xEnv, aNewTitle );
1144cdf0e10cSrcweir 
1145cdf0e10cSrcweir         // Retry inserting the content.
1146cdf0e10cSrcweir         try
1147cdf0e10cSrcweir         {
1148cdf0e10cSrcweir             // Previous try may have read from stream. Seek to begin (if
1149cdf0e10cSrcweir             // optional interface XSeekable is supported) or get a new stream.
1150cdf0e10cSrcweir             if ( xInputStream.is() )
1151cdf0e10cSrcweir             {
1152cdf0e10cSrcweir                 uno::Reference< io::XSeekable > xSeekable(
1153cdf0e10cSrcweir                     xInputStream, uno::UNO_QUERY );
1154cdf0e10cSrcweir                 if ( xSeekable.is() )
1155cdf0e10cSrcweir                 {
1156cdf0e10cSrcweir                     try
1157cdf0e10cSrcweir                     {
1158cdf0e10cSrcweir                         xSeekable->seek( 0 );
1159cdf0e10cSrcweir                     }
1160cdf0e10cSrcweir                     catch ( lang::IllegalArgumentException const & )
1161cdf0e10cSrcweir                     {
1162cdf0e10cSrcweir                         xInputStream.clear();
1163cdf0e10cSrcweir                     }
1164cdf0e10cSrcweir                     catch ( io::IOException const & )
1165cdf0e10cSrcweir                     {
1166cdf0e10cSrcweir                         xInputStream.clear();
1167cdf0e10cSrcweir                     }
1168cdf0e10cSrcweir                 }
1169cdf0e10cSrcweir                 else
1170cdf0e10cSrcweir                     xInputStream.clear();
1171cdf0e10cSrcweir 
1172cdf0e10cSrcweir                 if ( !xInputStream.is() )
1173cdf0e10cSrcweir                 {
1174cdf0e10cSrcweir                     xInputStream
1175cdf0e10cSrcweir                         = getInputStream( rContext, xCommandProcessorS );
1176cdf0e10cSrcweir                     if ( !xInputStream.is() )
1177cdf0e10cSrcweir                     {
1178cdf0e10cSrcweir                         uno::Any aProps2
1179cdf0e10cSrcweir                             = uno::makeAny(
1180cdf0e10cSrcweir                                 beans::PropertyValue(
1181cdf0e10cSrcweir                                     rtl::OUString(
1182cdf0e10cSrcweir                                         RTL_CONSTASCII_USTRINGPARAM( "Uri" ) ),
1183cdf0e10cSrcweir                                     -1,
1184cdf0e10cSrcweir                                     uno::makeAny(
1185cdf0e10cSrcweir                                         xNew->getIdentifier()->
1186cdf0e10cSrcweir                                             getContentIdentifier() ),
1187cdf0e10cSrcweir                                     beans::PropertyState_DIRECT_VALUE ) );
1188cdf0e10cSrcweir                         ucbhelper::cancelCommandExecution(
1189cdf0e10cSrcweir                             ucb::IOErrorCode_CANT_READ,
1190cdf0e10cSrcweir                             uno::Sequence< uno::Any >( &aProps2, 1 ),
1191cdf0e10cSrcweir                             rContext.xOrigEnv,
1192cdf0e10cSrcweir                             rtl::OUString::createFromAscii(
1193cdf0e10cSrcweir                                 "Got no data stream from source!" ),
1194cdf0e10cSrcweir                             rContext.xProcessor );
1195cdf0e10cSrcweir                         // Unreachable
1196cdf0e10cSrcweir                     }
1197cdf0e10cSrcweir                 }
1198cdf0e10cSrcweir             }
1199cdf0e10cSrcweir 
1200cdf0e10cSrcweir             ucb::InsertCommandArgument aArg;
1201cdf0e10cSrcweir             aArg.Data = xInputStream;
1202cdf0e10cSrcweir             aArg.ReplaceExisting = sal_False;
1203cdf0e10cSrcweir 
1204cdf0e10cSrcweir             ucb::Command aInsertCommand(
1205cdf0e10cSrcweir                         rtl::OUString::createFromAscii( "insert" ),
1206cdf0e10cSrcweir                         -1,
1207cdf0e10cSrcweir                         uno::makeAny( aArg ) );
1208cdf0e10cSrcweir 
1209cdf0e10cSrcweir             xCommandProcessorN->execute( aInsertCommand, 0, rContext.xEnv );
1210cdf0e10cSrcweir 
1211cdf0e10cSrcweir             // Success!
1212cdf0e10cSrcweir             bContinue = sal_False;
1213cdf0e10cSrcweir         }
1214cdf0e10cSrcweir         catch ( uno::RuntimeException const & )
1215cdf0e10cSrcweir         {
1216cdf0e10cSrcweir             throw;
1217cdf0e10cSrcweir         }
1218cdf0e10cSrcweir         catch ( uno::Exception const & )
1219cdf0e10cSrcweir         {
1220cdf0e10cSrcweir         }
1221cdf0e10cSrcweir     }
1222cdf0e10cSrcweir     while ( bContinue && ( nTry < 50 ) );
1223cdf0e10cSrcweir 
1224cdf0e10cSrcweir     if ( nTry == 50 )
1225cdf0e10cSrcweir     {
1226cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
1227cdf0e10cSrcweir             uno::makeAny(
1228cdf0e10cSrcweir                 ucb::UnsupportedNameClashException(
1229cdf0e10cSrcweir                     rtl::OUString::createFromAscii(
1230cdf0e10cSrcweir                         "Unable to resolve name clash!" ),
1231cdf0e10cSrcweir                     rContext.xProcessor,
1232cdf0e10cSrcweir                     ucb::NameClash::RENAME ) ),
1233cdf0e10cSrcweir             rContext.xOrigEnv );
1234cdf0e10cSrcweir         // Unreachable
1235cdf0e10cSrcweir     }
1236cdf0e10cSrcweir }
1237cdf0e10cSrcweir 
1238cdf0e10cSrcweir //=========================================================================
globalTransfer_(const TransferCommandContext & rContext,const uno::Reference<ucb::XContent> & xSource,const uno::Reference<ucb::XContent> & xTarget,const uno::Reference<sdbc::XRow> & xSourceProps)1239cdf0e10cSrcweir void globalTransfer_(
1240cdf0e10cSrcweir         const TransferCommandContext & rContext,
1241cdf0e10cSrcweir         const uno::Reference< ucb::XContent > & xSource,
1242cdf0e10cSrcweir         const uno::Reference< ucb::XContent > & xTarget,
1243cdf0e10cSrcweir         const uno::Reference< sdbc::XRow > & xSourceProps )
1244cdf0e10cSrcweir     throw( uno::Exception )
1245cdf0e10cSrcweir {
1246cdf0e10cSrcweir     // IsFolder: property is required.
1247cdf0e10cSrcweir     sal_Bool bSourceIsFolder = xSourceProps->getBoolean( 1 );
1248cdf0e10cSrcweir     if ( !bSourceIsFolder && xSourceProps->wasNull() )
1249cdf0e10cSrcweir     {
1250cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
1251cdf0e10cSrcweir             uno::makeAny( beans::UnknownPropertyException(
1252cdf0e10cSrcweir                             rtl::OUString::createFromAscii(
1253cdf0e10cSrcweir                                 "Unable to get property 'IsFolder' "
1254cdf0e10cSrcweir                                 "from source object!" ),
1255cdf0e10cSrcweir                             rContext.xProcessor ) ),
1256cdf0e10cSrcweir             rContext.xOrigEnv );
1257cdf0e10cSrcweir         // Unreachable
1258cdf0e10cSrcweir     }
1259cdf0e10cSrcweir 
1260cdf0e10cSrcweir     // IsDocument: property is required.
1261cdf0e10cSrcweir     sal_Bool bSourceIsDocument = xSourceProps->getBoolean( 2 );
1262cdf0e10cSrcweir     if ( !bSourceIsDocument && xSourceProps->wasNull() )
1263cdf0e10cSrcweir     {
1264cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
1265cdf0e10cSrcweir             uno::makeAny( beans::UnknownPropertyException(
1266cdf0e10cSrcweir                             rtl::OUString::createFromAscii(
1267cdf0e10cSrcweir                                 "Unable to get property 'IsDocument' "
1268cdf0e10cSrcweir                                 "from source object!" ),
1269cdf0e10cSrcweir                             rContext.xProcessor ) ),
1270cdf0e10cSrcweir             rContext.xOrigEnv );
1271cdf0e10cSrcweir         // Unreachable
1272cdf0e10cSrcweir     }
1273cdf0e10cSrcweir 
1274cdf0e10cSrcweir     // TargetURL: property is optional.
1275cdf0e10cSrcweir     sal_Bool bSourceIsLink = ( xSourceProps->getString( 3 ).getLength() > 0 );
1276cdf0e10cSrcweir 
1277cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
1278cdf0e10cSrcweir     //
1279cdf0e10cSrcweir     // (1) Try to find a matching target type for the source object and
1280cdf0e10cSrcweir     //     create a new, empty object of that type.
1281cdf0e10cSrcweir     //
1282cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
1283cdf0e10cSrcweir 
1284cdf0e10cSrcweir     uno::Reference< ucb::XContent > xNew = createNew( rContext,
1285cdf0e10cSrcweir                                                       xTarget,
1286cdf0e10cSrcweir                                                       bSourceIsFolder,
1287cdf0e10cSrcweir                                                       bSourceIsDocument,
1288cdf0e10cSrcweir                                                       bSourceIsLink );
1289cdf0e10cSrcweir     if ( !xNew.is() )
1290cdf0e10cSrcweir     {
1291cdf0e10cSrcweir         uno::Any aProps
1292cdf0e10cSrcweir             = uno::makeAny(beans::PropertyValue(
1293cdf0e10cSrcweir                                   rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1294cdf0e10cSrcweir                                       "Folder")),
1295cdf0e10cSrcweir                                   -1,
1296cdf0e10cSrcweir                                   uno::makeAny(rContext.aArg.TargetURL),
1297cdf0e10cSrcweir                                   beans::PropertyState_DIRECT_VALUE));
1298cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
1299cdf0e10cSrcweir             ucb::IOErrorCode_CANT_CREATE,
1300cdf0e10cSrcweir             uno::Sequence< uno::Any >(&aProps, 1),
1301cdf0e10cSrcweir             rContext.xOrigEnv,
1302cdf0e10cSrcweir             rtl::OUString::createFromAscii(
1303cdf0e10cSrcweir                 "No matching content type at target!" ),
1304cdf0e10cSrcweir             rContext.xProcessor );
1305cdf0e10cSrcweir         // Unreachable
1306cdf0e10cSrcweir     }
1307cdf0e10cSrcweir 
1308cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
1309cdf0e10cSrcweir     //
1310cdf0e10cSrcweir     // (2) Transfer property values from source to new object.
1311cdf0e10cSrcweir     //
1312cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
1313cdf0e10cSrcweir 
1314cdf0e10cSrcweir     uno::Reference< ucb::XCommandProcessor > xCommandProcessorN(
1315cdf0e10cSrcweir                                                     xNew, uno::UNO_QUERY );
1316cdf0e10cSrcweir     if ( !xCommandProcessorN.is() )
1317cdf0e10cSrcweir     {
1318cdf0e10cSrcweir         uno::Any aProps
1319cdf0e10cSrcweir             = uno::makeAny(beans::PropertyValue(
1320cdf0e10cSrcweir                                   rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1321cdf0e10cSrcweir                                                     "Uri")),
1322cdf0e10cSrcweir                                   -1,
1323cdf0e10cSrcweir                                   uno::makeAny(
1324cdf0e10cSrcweir                                       xNew->getIdentifier()->
1325cdf0e10cSrcweir                                                 getContentIdentifier()),
1326cdf0e10cSrcweir                                   beans::PropertyState_DIRECT_VALUE));
1327cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
1328cdf0e10cSrcweir             ucb::IOErrorCode_CANT_WRITE,
1329cdf0e10cSrcweir             uno::Sequence< uno::Any >(&aProps, 1),
1330cdf0e10cSrcweir             rContext.xOrigEnv,
1331cdf0e10cSrcweir             rtl::OUString::createFromAscii(
1332cdf0e10cSrcweir                 "New content is not a XCommandProcessor!" ),
1333cdf0e10cSrcweir             rContext.xProcessor );
1334cdf0e10cSrcweir         // Unreachable
1335cdf0e10cSrcweir     }
1336cdf0e10cSrcweir 
1337cdf0e10cSrcweir     // Obtain all properties from source.
1338cdf0e10cSrcweir 
1339cdf0e10cSrcweir     uno::Reference< ucb::XCommandProcessor > xCommandProcessorS(
1340cdf0e10cSrcweir                                                     xSource, uno::UNO_QUERY );
1341cdf0e10cSrcweir     if ( !xCommandProcessorS.is() )
1342cdf0e10cSrcweir     {
1343cdf0e10cSrcweir         uno::Any aProps
1344cdf0e10cSrcweir             = uno::makeAny(beans::PropertyValue(
1345cdf0e10cSrcweir                                   rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1346cdf0e10cSrcweir                                                     "Uri")),
1347cdf0e10cSrcweir                                   -1,
1348cdf0e10cSrcweir                                   uno::makeAny(rContext.aArg.SourceURL),
1349cdf0e10cSrcweir                                   beans::PropertyState_DIRECT_VALUE));
1350cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
1351cdf0e10cSrcweir             ucb::IOErrorCode_CANT_READ,
1352cdf0e10cSrcweir             uno::Sequence< uno::Any >(&aProps, 1),
1353cdf0e10cSrcweir             rContext.xOrigEnv,
1354cdf0e10cSrcweir             rtl::OUString::createFromAscii(
1355cdf0e10cSrcweir                 "Source content is not a XCommandProcessor!" ),
1356cdf0e10cSrcweir             rContext.xProcessor );
1357cdf0e10cSrcweir         // Unreachable
1358cdf0e10cSrcweir     }
1359cdf0e10cSrcweir 
1360cdf0e10cSrcweir     transferProperties( rContext, xCommandProcessorS, xCommandProcessorN );
1361cdf0e10cSrcweir 
1362cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
1363cdf0e10cSrcweir     //
1364cdf0e10cSrcweir     // (3) Try to obtain a data stream from source.
1365cdf0e10cSrcweir     //
1366cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
1367cdf0e10cSrcweir 
1368cdf0e10cSrcweir     uno::Reference< io::XInputStream > xInputStream;
1369cdf0e10cSrcweir 
1370cdf0e10cSrcweir     if ( bSourceIsDocument && ( rContext.aArg.Operation
1371cdf0e10cSrcweir                                 != ucb::TransferCommandOperation_LINK ) )
1372cdf0e10cSrcweir         xInputStream = getInputStream( rContext, xCommandProcessorS );
1373cdf0e10cSrcweir 
1374cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
1375cdf0e10cSrcweir     //
1376cdf0e10cSrcweir     // (4) Try to obtain a resultset (children) from source.
1377cdf0e10cSrcweir     //
1378cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
1379cdf0e10cSrcweir 
1380cdf0e10cSrcweir     uno::Reference< sdbc::XResultSet > xResultSet;
1381cdf0e10cSrcweir 
1382cdf0e10cSrcweir     if ( bSourceIsFolder && ( rContext.aArg.Operation
1383cdf0e10cSrcweir                                 != ucb::TransferCommandOperation_LINK ) )
1384cdf0e10cSrcweir         xResultSet = getResultSet( rContext, xCommandProcessorS );
1385cdf0e10cSrcweir 
1386cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
1387cdf0e10cSrcweir     //
1388cdf0e10cSrcweir     // (5) Insert (store) new content.
1389cdf0e10cSrcweir     //
1390cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
1391cdf0e10cSrcweir 
1392cdf0e10cSrcweir     ucb::InsertCommandArgument aArg;
1393cdf0e10cSrcweir     aArg.Data = xInputStream;
1394cdf0e10cSrcweir 
1395cdf0e10cSrcweir     switch ( rContext.aArg.NameClash )
1396cdf0e10cSrcweir     {
1397cdf0e10cSrcweir         case ucb::NameClash::OVERWRITE:
1398cdf0e10cSrcweir             aArg.ReplaceExisting = sal_True;
1399cdf0e10cSrcweir             break;
1400cdf0e10cSrcweir 
1401cdf0e10cSrcweir         case ucb::NameClash::ERROR:
1402cdf0e10cSrcweir         case ucb::NameClash::RENAME:
1403cdf0e10cSrcweir         case ucb::NameClash::KEEP: // deprecated
1404cdf0e10cSrcweir         case ucb::NameClash::ASK:
1405cdf0e10cSrcweir             aArg.ReplaceExisting = sal_False;
1406cdf0e10cSrcweir             break;
1407cdf0e10cSrcweir 
1408cdf0e10cSrcweir         default:
1409cdf0e10cSrcweir             aArg.ReplaceExisting = sal_False;
1410cdf0e10cSrcweir             OSL_ENSURE( sal_False, "Unknown nameclash directive!" );
1411cdf0e10cSrcweir             break;
1412cdf0e10cSrcweir     }
1413cdf0e10cSrcweir 
1414cdf0e10cSrcweir     rtl::OUString aDesiredName = createDesiredName( rContext.aArg );
1415cdf0e10cSrcweir 
1416cdf0e10cSrcweir     bool bRetry;
1417cdf0e10cSrcweir     do
1418cdf0e10cSrcweir     {
1419cdf0e10cSrcweir         bRetry = false;
1420cdf0e10cSrcweir 
1421cdf0e10cSrcweir         try
1422cdf0e10cSrcweir         {
1423cdf0e10cSrcweir             ucb::Command aInsertCommand(
1424cdf0e10cSrcweir                                     rtl::OUString::createFromAscii( "insert" ),
1425cdf0e10cSrcweir                                     -1,
1426cdf0e10cSrcweir                                     uno::makeAny( aArg ) );
1427cdf0e10cSrcweir 
1428cdf0e10cSrcweir             xCommandProcessorN->execute( aInsertCommand, 0, rContext.xEnv );
1429cdf0e10cSrcweir         }
1430cdf0e10cSrcweir         catch ( ucb::UnsupportedNameClashException const & exc )
1431cdf0e10cSrcweir         {
1432cdf0e10cSrcweir             OSL_ENSURE( !aArg.ReplaceExisting,
1433cdf0e10cSrcweir                         "BUG: UnsupportedNameClashException not allowed here!" );
1434cdf0e10cSrcweir 
1435cdf0e10cSrcweir             if (exc.NameClash != ucb::NameClash::ERROR) {
1436cdf0e10cSrcweir                 OSL_ENSURE( false, "BUG: NameClash::ERROR expected!" );
1437cdf0e10cSrcweir             }
1438cdf0e10cSrcweir 
1439cdf0e10cSrcweir             // No chance to solve name clashes, because I'm not able to detect
1440cdf0e10cSrcweir             // whether there is one.
1441cdf0e10cSrcweir             throw ucb::UnsupportedNameClashException(
1442cdf0e10cSrcweir                     rtl::OUString::createFromAscii(
1443cdf0e10cSrcweir                         "Unable to resolve name clashes, no chance to detect "
1444cdf0e10cSrcweir                         "that there is one!" ),
1445cdf0e10cSrcweir                     rContext.xProcessor,
1446cdf0e10cSrcweir                     rContext.aArg.NameClash );
1447cdf0e10cSrcweir         }
1448cdf0e10cSrcweir         catch ( ucb::NameClashException const & )
1449cdf0e10cSrcweir         {
1450cdf0e10cSrcweir             // The 'insert' command throws a NameClashException if the parameter
1451cdf0e10cSrcweir             // ReplaceExisting of the command's argument was set to false and
1452cdf0e10cSrcweir             // there exists a resource with a clashing name in the target folder
1453cdf0e10cSrcweir             // of the operation.
1454cdf0e10cSrcweir 
1455cdf0e10cSrcweir             // 'insert' command has no direct support for name clashes other
1456cdf0e10cSrcweir             // than ERROR ( ReplaceExisting == false ) and OVERWRITE
1457cdf0e10cSrcweir             // ( ReplaceExisting == true ). So we have to implement the
1458cdf0e10cSrcweir             // other name clash handling directives on top of the content.
1459cdf0e10cSrcweir 
1460cdf0e10cSrcweir             // @@@ 'insert' command should be extended that it accepts a
1461cdf0e10cSrcweir             //     name clash handling directive, exactly like 'transfer' command.
1462cdf0e10cSrcweir 
1463cdf0e10cSrcweir             switch ( rContext.aArg.NameClash )
1464cdf0e10cSrcweir             {
1465cdf0e10cSrcweir                 case ucb::NameClash::OVERWRITE:
1466cdf0e10cSrcweir                 {
1467cdf0e10cSrcweir                     ucbhelper::cancelCommandExecution(
1468cdf0e10cSrcweir                         uno::makeAny(
1469cdf0e10cSrcweir                             ucb::UnsupportedNameClashException(
1470cdf0e10cSrcweir                                 rtl::OUString::createFromAscii(
1471cdf0e10cSrcweir                                     "BUG: insert + replace == true MUST NOT "
1472cdf0e10cSrcweir                                     "throw NameClashException." ),
1473cdf0e10cSrcweir                                 rContext.xProcessor,
1474cdf0e10cSrcweir                                 rContext.aArg.NameClash ) ),
1475cdf0e10cSrcweir                         rContext.xOrigEnv );
1476cdf0e10cSrcweir                     // Unreachable
1477cdf0e10cSrcweir                 }
1478cdf0e10cSrcweir 
1479cdf0e10cSrcweir                 case ucb::NameClash::ERROR:
1480cdf0e10cSrcweir                     throw;
1481cdf0e10cSrcweir 
1482cdf0e10cSrcweir                 case ucb::NameClash::RENAME:
1483cdf0e10cSrcweir                 {
1484cdf0e10cSrcweir                     // "invent" a new valid title.
1485cdf0e10cSrcweir                     handleNameClashRename( rContext,
1486cdf0e10cSrcweir                                            xNew,
1487cdf0e10cSrcweir                                            xCommandProcessorN,
1488cdf0e10cSrcweir                                            xCommandProcessorS,
1489cdf0e10cSrcweir                                            xInputStream );
1490cdf0e10cSrcweir                     break;
1491cdf0e10cSrcweir                 }
1492cdf0e10cSrcweir 
1493cdf0e10cSrcweir                 case ucb::NameClash::ASK:
1494cdf0e10cSrcweir                     {
1495cdf0e10cSrcweir                         uno::Any aExc;
1496cdf0e10cSrcweir                         rtl::OUString aNewTitle;
1497cdf0e10cSrcweir                         NameClashContinuation eCont
1498cdf0e10cSrcweir                             = interactiveNameClashResolve(
1499cdf0e10cSrcweir                                 rContext.xOrigEnv, // always use original environment!
1500cdf0e10cSrcweir                                 rContext.aArg.TargetURL, // target folder URL
1501cdf0e10cSrcweir                                 aDesiredName,
1502cdf0e10cSrcweir                                 aExc,
1503cdf0e10cSrcweir                                 aNewTitle );
1504cdf0e10cSrcweir 
1505cdf0e10cSrcweir                         switch ( eCont )
1506cdf0e10cSrcweir                         {
1507cdf0e10cSrcweir                             case NOT_HANDLED:
1508cdf0e10cSrcweir                                 // Not handled.
1509cdf0e10cSrcweir                                 cppu::throwException( aExc );
1510cdf0e10cSrcweir     //                            break;
1511cdf0e10cSrcweir 
1512cdf0e10cSrcweir                             case UNKNOWN:
1513cdf0e10cSrcweir                                 // Handled, but not clear, how...
1514cdf0e10cSrcweir                                 // fall-thru intended.
1515cdf0e10cSrcweir 
1516cdf0e10cSrcweir                             case ABORT:
1517cdf0e10cSrcweir                                 throw ucb::CommandFailedException(
1518cdf0e10cSrcweir                                     rtl::OUString(
1519cdf0e10cSrcweir                                         RTL_CONSTASCII_USTRINGPARAM(
1520cdf0e10cSrcweir                                             "abort requested via interaction "
1521cdf0e10cSrcweir                                             "handler" ) ),
1522cdf0e10cSrcweir                                     uno::Reference< uno::XInterface >(),
1523cdf0e10cSrcweir                                     aExc );
1524cdf0e10cSrcweir     //                            break;
1525cdf0e10cSrcweir 
1526cdf0e10cSrcweir                             case OVERWRITE:
1527cdf0e10cSrcweir                                 OSL_ENSURE( aArg.ReplaceExisting == sal_False,
1528cdf0e10cSrcweir                                             "Hu? ReplaceExisting already true?"
1529cdf0e10cSrcweir                                           );
1530cdf0e10cSrcweir                                 aArg.ReplaceExisting = sal_True;
1531cdf0e10cSrcweir                                 bRetry = true;
1532cdf0e10cSrcweir                                 break;
1533cdf0e10cSrcweir 
1534cdf0e10cSrcweir                             case NEW_NAME:
1535cdf0e10cSrcweir                             {
1536cdf0e10cSrcweir                                 // set new name -> set "Title" property...
1537cdf0e10cSrcweir                                 if ( setTitle( xCommandProcessorN,
1538cdf0e10cSrcweir                                                rContext.xEnv,
1539cdf0e10cSrcweir                                                aNewTitle ) )
1540cdf0e10cSrcweir                                 {
1541cdf0e10cSrcweir                                     // remember suggested title...
1542cdf0e10cSrcweir                                     aDesiredName = aNewTitle;
1543cdf0e10cSrcweir 
1544cdf0e10cSrcweir                                     // ... and try again.
1545cdf0e10cSrcweir                                     bRetry = true;
1546cdf0e10cSrcweir                                 }
1547cdf0e10cSrcweir                                 else
1548cdf0e10cSrcweir                                 {
1549cdf0e10cSrcweir                                     // error setting title. Abort.
1550cdf0e10cSrcweir                                     throw ucb::CommandFailedException(
1551cdf0e10cSrcweir                                         rtl::OUString(
1552cdf0e10cSrcweir                                             RTL_CONSTASCII_USTRINGPARAM(
1553cdf0e10cSrcweir                                                 "error setting Title property!"
1554cdf0e10cSrcweir                                             ) ),
1555cdf0e10cSrcweir                                         uno::Reference< uno::XInterface >(),
1556cdf0e10cSrcweir                                         aExc );
1557cdf0e10cSrcweir                                 }
1558cdf0e10cSrcweir                                 break;
1559cdf0e10cSrcweir                             }
1560cdf0e10cSrcweir                         }
1561cdf0e10cSrcweir 
1562cdf0e10cSrcweir                         OSL_ENSURE( bRetry, "bRetry must be true here!!!" );
1563cdf0e10cSrcweir                     }
1564cdf0e10cSrcweir                     break;
1565cdf0e10cSrcweir 
1566cdf0e10cSrcweir                 case ucb::NameClash::KEEP: // deprecated
1567cdf0e10cSrcweir                 default:
1568cdf0e10cSrcweir                 {
1569cdf0e10cSrcweir                     ucbhelper::cancelCommandExecution(
1570cdf0e10cSrcweir                         uno::makeAny(
1571cdf0e10cSrcweir                             ucb::UnsupportedNameClashException(
1572cdf0e10cSrcweir                                 rtl::OUString(
1573cdf0e10cSrcweir                                     RTL_CONSTASCII_USTRINGPARAM(
1574cdf0e10cSrcweir                                         "default action, don't know how to "
1575cdf0e10cSrcweir                                         "handle name clash" ) ),
1576cdf0e10cSrcweir                                 rContext.xProcessor,
1577cdf0e10cSrcweir                                 rContext.aArg.NameClash ) ),
1578cdf0e10cSrcweir                         rContext.xOrigEnv );
1579cdf0e10cSrcweir                     // Unreachable
1580cdf0e10cSrcweir                 }
1581cdf0e10cSrcweir             }
1582cdf0e10cSrcweir         }
1583cdf0e10cSrcweir     }
1584cdf0e10cSrcweir     while ( bRetry );
1585cdf0e10cSrcweir 
1586cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
1587cdf0e10cSrcweir     //
1588cdf0e10cSrcweir     // (6) Process children of source.
1589cdf0e10cSrcweir     //
1590cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
1591cdf0e10cSrcweir 
1592cdf0e10cSrcweir     if ( xResultSet.is() )
1593cdf0e10cSrcweir     {
1594cdf0e10cSrcweir         try
1595cdf0e10cSrcweir         {
1596cdf0e10cSrcweir             // Iterate over children...
1597cdf0e10cSrcweir 
1598cdf0e10cSrcweir             uno::Reference< sdbc::XRow > xChildRow(
1599cdf0e10cSrcweir                                             xResultSet, uno::UNO_QUERY );
1600cdf0e10cSrcweir 
1601cdf0e10cSrcweir             if ( !xChildRow.is() )
1602cdf0e10cSrcweir             {
1603cdf0e10cSrcweir                 uno::Any aProps
1604cdf0e10cSrcweir                     = uno::makeAny(
1605cdf0e10cSrcweir                              beans::PropertyValue(
1606cdf0e10cSrcweir                                  rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1607cdf0e10cSrcweir                                                    "Uri")),
1608cdf0e10cSrcweir                                  -1,
1609cdf0e10cSrcweir                                  uno::makeAny(rContext.aArg.SourceURL),
1610cdf0e10cSrcweir                                  beans::PropertyState_DIRECT_VALUE));
1611cdf0e10cSrcweir                 ucbhelper::cancelCommandExecution(
1612cdf0e10cSrcweir                     ucb::IOErrorCode_CANT_READ,
1613cdf0e10cSrcweir                     uno::Sequence< uno::Any >(&aProps, 1),
1614cdf0e10cSrcweir                     rContext.xOrigEnv,
1615cdf0e10cSrcweir                     rtl::OUString::createFromAscii(
1616cdf0e10cSrcweir                         "Unable to get properties from children of source!" ),
1617cdf0e10cSrcweir                     rContext.xProcessor );
1618cdf0e10cSrcweir                 // Unreachable
1619cdf0e10cSrcweir             }
1620cdf0e10cSrcweir 
1621cdf0e10cSrcweir             uno::Reference< ucb::XContentAccess > xChildAccess(
1622cdf0e10cSrcweir                                                 xResultSet, uno::UNO_QUERY );
1623cdf0e10cSrcweir 
1624cdf0e10cSrcweir             if ( !xChildAccess.is() )
1625cdf0e10cSrcweir             {
1626cdf0e10cSrcweir                 uno::Any aProps
1627cdf0e10cSrcweir                     = uno::makeAny(
1628cdf0e10cSrcweir                              beans::PropertyValue(
1629cdf0e10cSrcweir                                  rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1630cdf0e10cSrcweir                                      "Uri")),
1631cdf0e10cSrcweir                                  -1,
1632cdf0e10cSrcweir                                  uno::makeAny(rContext.aArg.SourceURL),
1633cdf0e10cSrcweir                                  beans::PropertyState_DIRECT_VALUE));
1634cdf0e10cSrcweir                 ucbhelper::cancelCommandExecution(
1635cdf0e10cSrcweir                     ucb::IOErrorCode_CANT_READ,
1636cdf0e10cSrcweir                     uno::Sequence< uno::Any >(&aProps, 1),
1637cdf0e10cSrcweir                     rContext.xOrigEnv,
1638cdf0e10cSrcweir                     rtl::OUString::createFromAscii(
1639cdf0e10cSrcweir                         "Unable to get children of source!" ),
1640cdf0e10cSrcweir                     rContext.xProcessor );
1641cdf0e10cSrcweir                 // Unreachable
1642cdf0e10cSrcweir             }
1643cdf0e10cSrcweir 
1644cdf0e10cSrcweir             if ( xResultSet->first() )
1645cdf0e10cSrcweir             {
1646cdf0e10cSrcweir                 ucb::GlobalTransferCommandArgument aTransArg(
1647cdf0e10cSrcweir                         rContext.aArg.Operation,      // Operation
1648cdf0e10cSrcweir                         rtl::OUString(),              // SourceURL; filled later
1649cdf0e10cSrcweir                         xNew->getIdentifier()
1650cdf0e10cSrcweir                             ->getContentIdentifier(), // TargetURL
1651cdf0e10cSrcweir                         rtl::OUString(),              // NewTitle;
1652cdf0e10cSrcweir                         rContext.aArg.NameClash );    // NameClash
1653cdf0e10cSrcweir 
1654cdf0e10cSrcweir                 TransferCommandContext aSubCtx(
1655cdf0e10cSrcweir                         rContext.xSMgr,
1656cdf0e10cSrcweir                         rContext.xProcessor,
1657cdf0e10cSrcweir                         rContext.xEnv,
1658cdf0e10cSrcweir                         rContext.xOrigEnv,
1659cdf0e10cSrcweir                         aTransArg );
1660cdf0e10cSrcweir                 do
1661cdf0e10cSrcweir                 {
1662cdf0e10cSrcweir                     uno::Reference< ucb::XContent > xChild
1663cdf0e10cSrcweir                                         = xChildAccess->queryContent();
1664cdf0e10cSrcweir                     if ( xChild.is() )
1665cdf0e10cSrcweir                     {
1666cdf0e10cSrcweir                         // Recursion!
1667cdf0e10cSrcweir 
1668cdf0e10cSrcweir                         aSubCtx.aArg.SourceURL
1669cdf0e10cSrcweir                             = xChild->getIdentifier()->getContentIdentifier();
1670cdf0e10cSrcweir 
1671cdf0e10cSrcweir                         globalTransfer_( aSubCtx,
1672cdf0e10cSrcweir                                          xChild,
1673cdf0e10cSrcweir                                          xNew,
1674cdf0e10cSrcweir                                          xChildRow );
1675cdf0e10cSrcweir                     }
1676cdf0e10cSrcweir                 }
1677cdf0e10cSrcweir                 while ( xResultSet->next() );
1678cdf0e10cSrcweir             }
1679cdf0e10cSrcweir         }
1680cdf0e10cSrcweir         catch ( sdbc::SQLException const & )
1681cdf0e10cSrcweir         {
1682cdf0e10cSrcweir         }
1683cdf0e10cSrcweir     }
1684cdf0e10cSrcweir 
1685cdf0e10cSrcweir     try {
1686cdf0e10cSrcweir         uno::Reference< ucb::XCommandProcessor > xcp(
1687cdf0e10cSrcweir             xTarget, uno::UNO_QUERY );
1688cdf0e10cSrcweir 
1689cdf0e10cSrcweir         uno::Any aAny;
1690cdf0e10cSrcweir         uno::Reference< ucb::XCommandInfo > xci;
1691cdf0e10cSrcweir         if(xcp.is())
1692cdf0e10cSrcweir             aAny =
1693cdf0e10cSrcweir                 xcp->execute(
1694cdf0e10cSrcweir                     ucb::Command(
1695cdf0e10cSrcweir                         rtl::OUString::createFromAscii("getCommandInfo"),
1696cdf0e10cSrcweir                         -1,
1697cdf0e10cSrcweir                         uno::Any()),
1698cdf0e10cSrcweir                     0,
1699cdf0e10cSrcweir                     rContext.xEnv );
1700cdf0e10cSrcweir 
1701cdf0e10cSrcweir         const rtl::OUString cmdName =
1702cdf0e10cSrcweir             rtl::OUString::createFromAscii("flush");
1703cdf0e10cSrcweir         if((aAny >>= xci) && xci->hasCommandByName(cmdName))
1704cdf0e10cSrcweir             xcp->execute(
1705cdf0e10cSrcweir                 ucb::Command(
1706cdf0e10cSrcweir                     cmdName,
1707cdf0e10cSrcweir                     -1,
1708cdf0e10cSrcweir                     uno::Any()) ,
1709cdf0e10cSrcweir                 0,
1710cdf0e10cSrcweir                 rContext.xEnv );
1711cdf0e10cSrcweir     }
1712cdf0e10cSrcweir     catch( uno::Exception const & )
1713cdf0e10cSrcweir     {
1714cdf0e10cSrcweir     }
1715cdf0e10cSrcweir }
1716cdf0e10cSrcweir 
1717cdf0e10cSrcweir } /* namescpace */
1718cdf0e10cSrcweir 
1719cdf0e10cSrcweir //=========================================================================
1720cdf0e10cSrcweir //
1721cdf0e10cSrcweir // UniversalContentBroker implementation ( XCommandProcessor commands ).
1722cdf0e10cSrcweir //
1723cdf0e10cSrcweir //=========================================================================
1724cdf0e10cSrcweir 
1725cdf0e10cSrcweir uno::Reference< ucb::XCommandInfo >
getCommandInfo()1726cdf0e10cSrcweir UniversalContentBroker::getCommandInfo()
1727cdf0e10cSrcweir {
1728cdf0e10cSrcweir     return uno::Reference< ucb::XCommandInfo >( new CommandProcessorInfo() );
1729cdf0e10cSrcweir }
1730cdf0e10cSrcweir 
1731cdf0e10cSrcweir //=========================================================================
globalTransfer(const ucb::GlobalTransferCommandArgument & rArg,const uno::Reference<ucb::XCommandEnvironment> & xEnv)1732cdf0e10cSrcweir void UniversalContentBroker::globalTransfer(
1733cdf0e10cSrcweir             const ucb::GlobalTransferCommandArgument & rArg,
1734cdf0e10cSrcweir             const uno::Reference< ucb::XCommandEnvironment > & xEnv )
1735cdf0e10cSrcweir     throw( uno::Exception )
1736cdf0e10cSrcweir {
1737cdf0e10cSrcweir     // Use own command environment with own interaction handler intercepting
1738cdf0e10cSrcweir     // some interaction requests that shall not be handled by the user-supplied
1739cdf0e10cSrcweir     // interaction handler.
1740cdf0e10cSrcweir     uno::Reference< ucb::XCommandEnvironment > xLocalEnv;
1741cdf0e10cSrcweir     if (xEnv.is())
1742cdf0e10cSrcweir     {
1743cdf0e10cSrcweir         uno::Reference< beans::XPropertySet > const xProps(
1744cdf0e10cSrcweir             m_xSMgr, uno::UNO_QUERY_THROW );
1745cdf0e10cSrcweir         uno::Reference< uno::XComponentContext > xCtx;
1746cdf0e10cSrcweir             xCtx.set( xProps->getPropertyValue(
1747cdf0e10cSrcweir                 rtl::OUString(
1748cdf0e10cSrcweir                     RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ),
1749cdf0e10cSrcweir                 uno::UNO_QUERY_THROW );
1750cdf0e10cSrcweir 
1751cdf0e10cSrcweir             xLocalEnv.set( ucb::CommandEnvironment::create(
1752cdf0e10cSrcweir                xCtx,
1753cdf0e10cSrcweir                new InteractionHandlerProxy( xEnv->getInteractionHandler() ),
1754cdf0e10cSrcweir                xEnv->getProgressHandler() ) );
1755cdf0e10cSrcweir     }
1756cdf0e10cSrcweir 
1757cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
1758cdf0e10cSrcweir     //
1759cdf0e10cSrcweir     // (1) Try to transfer the content using 'transfer' command.
1760cdf0e10cSrcweir     //
1761cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
1762cdf0e10cSrcweir 
1763cdf0e10cSrcweir     uno::Reference< ucb::XContent > xTarget;
1764cdf0e10cSrcweir     uno::Reference< ucb::XContentIdentifier > xId
1765cdf0e10cSrcweir             = createContentIdentifier( rArg.TargetURL );
1766cdf0e10cSrcweir     if ( xId.is() )
1767cdf0e10cSrcweir     {
1768cdf0e10cSrcweir         try
1769cdf0e10cSrcweir         {
1770cdf0e10cSrcweir             xTarget = queryContent( xId );
1771cdf0e10cSrcweir         }
1772cdf0e10cSrcweir         catch ( ucb::IllegalIdentifierException const & )
1773cdf0e10cSrcweir         {
1774cdf0e10cSrcweir         }
1775cdf0e10cSrcweir     }
1776cdf0e10cSrcweir 
1777cdf0e10cSrcweir     if ( !xTarget.is() )
1778cdf0e10cSrcweir     {
1779cdf0e10cSrcweir         uno::Any aProps
1780cdf0e10cSrcweir             = uno::makeAny(beans::PropertyValue(
1781cdf0e10cSrcweir                                   rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1782cdf0e10cSrcweir                                       "Uri")),
1783cdf0e10cSrcweir                                   -1,
1784cdf0e10cSrcweir                                   uno::makeAny(rArg.TargetURL),
1785cdf0e10cSrcweir                                   beans::PropertyState_DIRECT_VALUE));
1786cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
1787cdf0e10cSrcweir             ucb::IOErrorCode_CANT_READ,
1788cdf0e10cSrcweir             uno::Sequence< uno::Any >(&aProps, 1),
1789cdf0e10cSrcweir             xEnv,
1790cdf0e10cSrcweir             rtl::OUString::createFromAscii(
1791cdf0e10cSrcweir                 "Can't instanciate target object!" ),
1792cdf0e10cSrcweir             this );
1793cdf0e10cSrcweir         // Unreachable
1794cdf0e10cSrcweir     }
1795cdf0e10cSrcweir 
1796cdf0e10cSrcweir     if ( ( rArg.Operation == ucb::TransferCommandOperation_COPY ) ||
1797cdf0e10cSrcweir          ( rArg.Operation == ucb::TransferCommandOperation_MOVE ) )
1798cdf0e10cSrcweir     {
1799cdf0e10cSrcweir         uno::Reference< ucb::XCommandProcessor > xCommandProcessor(
1800cdf0e10cSrcweir                                                     xTarget, uno::UNO_QUERY );
1801cdf0e10cSrcweir         if ( !xCommandProcessor.is() )
1802cdf0e10cSrcweir         {
1803cdf0e10cSrcweir             uno::Any aProps
1804cdf0e10cSrcweir                 = uno::makeAny(
1805cdf0e10cSrcweir                          beans::PropertyValue(
1806cdf0e10cSrcweir                              rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1807cdf0e10cSrcweir                                                "Uri")),
1808cdf0e10cSrcweir                              -1,
1809cdf0e10cSrcweir                              uno::makeAny(rArg.TargetURL),
1810cdf0e10cSrcweir                              beans::PropertyState_DIRECT_VALUE));
1811cdf0e10cSrcweir             ucbhelper::cancelCommandExecution(
1812cdf0e10cSrcweir                 ucb::IOErrorCode_CANT_READ,
1813cdf0e10cSrcweir                 uno::Sequence< uno::Any >(&aProps, 1),
1814cdf0e10cSrcweir                 xEnv,
1815cdf0e10cSrcweir                 rtl::OUString::createFromAscii(
1816cdf0e10cSrcweir                     "Target content is not a XCommandProcessor!" ),
1817cdf0e10cSrcweir                 this );
1818cdf0e10cSrcweir             // Unreachable
1819cdf0e10cSrcweir         }
1820cdf0e10cSrcweir 
1821cdf0e10cSrcweir         ucb::TransferInfo aTransferArg(
1822cdf0e10cSrcweir             ( rArg.Operation
1823cdf0e10cSrcweir                 == ucb::TransferCommandOperation_MOVE ), // MoveData
1824cdf0e10cSrcweir             rArg.SourceURL,   // SourceURL
1825cdf0e10cSrcweir             rArg.NewTitle,    // NewTitle
1826cdf0e10cSrcweir             rArg.NameClash ); // NameClash
1827cdf0e10cSrcweir 
1828cdf0e10cSrcweir         bool bRetry;
1829cdf0e10cSrcweir         do
1830cdf0e10cSrcweir         {
1831cdf0e10cSrcweir             bRetry = false;
1832cdf0e10cSrcweir 
1833cdf0e10cSrcweir             try
1834cdf0e10cSrcweir             {
1835cdf0e10cSrcweir                 ucb::Command aCommand(
1836cdf0e10cSrcweir                     rtl::OUString::createFromAscii( "transfer" ), // Name
1837cdf0e10cSrcweir                     -1,                                           // Handle
1838cdf0e10cSrcweir                     uno::makeAny( aTransferArg ) );               // Argument
1839cdf0e10cSrcweir 
1840cdf0e10cSrcweir                 xCommandProcessor->execute( aCommand, 0, xLocalEnv );
1841cdf0e10cSrcweir 
1842cdf0e10cSrcweir                 // Command succeeded. We're done.
1843cdf0e10cSrcweir                 return;
1844cdf0e10cSrcweir             }
1845cdf0e10cSrcweir             catch ( ucb::InteractiveBadTransferURLException const & )
1846cdf0e10cSrcweir             {
1847cdf0e10cSrcweir                 // Source URL is not supported by target. Try to transfer
1848cdf0e10cSrcweir                 // the content "manually".
1849cdf0e10cSrcweir             }
1850cdf0e10cSrcweir             catch ( ucb::UnsupportedCommandException const & )
1851cdf0e10cSrcweir             {
1852cdf0e10cSrcweir                 // 'transfer' command is not supported by commandprocessor.
1853cdf0e10cSrcweir                 // Try to transfer manually.
1854cdf0e10cSrcweir             }
1855cdf0e10cSrcweir             catch ( ucb::UnsupportedNameClashException const & exc )
1856cdf0e10cSrcweir             {
1857cdf0e10cSrcweir                 OSL_ENSURE( aTransferArg.NameClash == exc.NameClash,
1858cdf0e10cSrcweir                             "nameclash mismatch!" );
1859cdf0e10cSrcweir                 if ( exc.NameClash == ucb::NameClash::ASK )
1860cdf0e10cSrcweir                 {
1861cdf0e10cSrcweir                     // Try to detect a name clash by invoking "transfer" with
1862cdf0e10cSrcweir                     // NameClash::ERROR.
1863cdf0e10cSrcweir                     try
1864cdf0e10cSrcweir                     {
1865cdf0e10cSrcweir                         ucb::TransferInfo aTransferArg1(
1866cdf0e10cSrcweir                             aTransferArg.MoveData,
1867cdf0e10cSrcweir                             aTransferArg.SourceURL,
1868cdf0e10cSrcweir                             aTransferArg.NewTitle,
1869cdf0e10cSrcweir                             ucb::NameClash::ERROR );
1870cdf0e10cSrcweir 
1871cdf0e10cSrcweir                         ucb::Command aCommand1(
1872cdf0e10cSrcweir                             rtl::OUString::createFromAscii( "transfer" ),
1873cdf0e10cSrcweir                             -1,
1874cdf0e10cSrcweir                             uno::makeAny( aTransferArg1 ) );
1875cdf0e10cSrcweir 
1876cdf0e10cSrcweir                         xCommandProcessor->execute( aCommand1, 0, xLocalEnv );
1877cdf0e10cSrcweir 
1878cdf0e10cSrcweir                         // Command succeeded. We're done.
1879cdf0e10cSrcweir                         return;
1880cdf0e10cSrcweir                     }
1881cdf0e10cSrcweir                     catch ( ucb::UnsupportedNameClashException const & )
1882cdf0e10cSrcweir                     {
1883cdf0e10cSrcweir                         // No chance to solve name clashes, because I'm not
1884cdf0e10cSrcweir                         // able to detect whether there is one.
1885cdf0e10cSrcweir                         throw exc; // Not just 'throw;'!
1886cdf0e10cSrcweir                     }
1887cdf0e10cSrcweir                     catch ( ucb::NameClashException const & )
1888cdf0e10cSrcweir                     {
1889cdf0e10cSrcweir                         // There's a clash. Use interaction handler to solve it.
1890cdf0e10cSrcweir 
1891cdf0e10cSrcweir                         uno::Any aExc;
1892cdf0e10cSrcweir                         rtl::OUString aNewTitle;
1893cdf0e10cSrcweir                         NameClashContinuation eCont
1894cdf0e10cSrcweir                             = interactiveNameClashResolve(
1895cdf0e10cSrcweir                                 xEnv, // always use original environment!
1896cdf0e10cSrcweir                                 rArg.TargetURL,  // target folder URL
1897cdf0e10cSrcweir                                 createDesiredName(
1898cdf0e10cSrcweir                                   aTransferArg ),   // clashing name
1899cdf0e10cSrcweir                                 aExc,
1900cdf0e10cSrcweir                                 aNewTitle );
1901cdf0e10cSrcweir 
1902cdf0e10cSrcweir                         switch ( eCont )
1903cdf0e10cSrcweir                         {
1904cdf0e10cSrcweir                             case NOT_HANDLED:
1905cdf0e10cSrcweir                                 // Not handled.
1906cdf0e10cSrcweir                                 cppu::throwException( aExc );
1907cdf0e10cSrcweir //                                break;
1908cdf0e10cSrcweir 
1909cdf0e10cSrcweir                             case UNKNOWN:
1910cdf0e10cSrcweir                                 // Handled, but not clear, how...
1911cdf0e10cSrcweir                                 // fall-thru intended.
1912cdf0e10cSrcweir 
1913cdf0e10cSrcweir                             case ABORT:
1914cdf0e10cSrcweir                                 throw ucb::CommandFailedException(
1915cdf0e10cSrcweir                                     rtl::OUString(
1916cdf0e10cSrcweir                                         RTL_CONSTASCII_USTRINGPARAM(
1917cdf0e10cSrcweir                                             "abort requested via interaction "
1918cdf0e10cSrcweir                                             "handler" ) ),
1919cdf0e10cSrcweir                                     uno::Reference< uno::XInterface >(),
1920cdf0e10cSrcweir                                     aExc );
1921cdf0e10cSrcweir //                                break;
1922cdf0e10cSrcweir 
1923cdf0e10cSrcweir                             case OVERWRITE:
1924cdf0e10cSrcweir                                 aTransferArg.NameClash
1925cdf0e10cSrcweir                                     = ucb::NameClash::OVERWRITE;
1926cdf0e10cSrcweir                                 bRetry = true;
1927cdf0e10cSrcweir                                 break;
1928cdf0e10cSrcweir 
1929cdf0e10cSrcweir                             case NEW_NAME:
1930cdf0e10cSrcweir                                 aTransferArg.NewTitle = aNewTitle;
1931cdf0e10cSrcweir                                 bRetry = true;
1932cdf0e10cSrcweir                                 break;
1933cdf0e10cSrcweir                         }
1934cdf0e10cSrcweir 
1935cdf0e10cSrcweir                         OSL_ENSURE( bRetry, "bRetry must be true here!!!" );
1936cdf0e10cSrcweir                     }
1937cdf0e10cSrcweir                 }
1938cdf0e10cSrcweir                 else
1939cdf0e10cSrcweir                 {
1940cdf0e10cSrcweir                     throw;
1941cdf0e10cSrcweir                 }
1942cdf0e10cSrcweir             }
1943cdf0e10cSrcweir         }
1944cdf0e10cSrcweir         while ( bRetry );
1945cdf0e10cSrcweir     }
1946cdf0e10cSrcweir 
1947cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
1948cdf0e10cSrcweir     //
1949cdf0e10cSrcweir     // (2) Try to transfer the content "manually".
1950cdf0e10cSrcweir     //
1951cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
1952cdf0e10cSrcweir 
1953cdf0e10cSrcweir     uno::Reference< ucb::XContent > xSource;
1954cdf0e10cSrcweir     try
1955cdf0e10cSrcweir     {
1956cdf0e10cSrcweir         uno::Reference< ucb::XContentIdentifier > xId2
1957cdf0e10cSrcweir             = createContentIdentifier( rArg.SourceURL );
1958cdf0e10cSrcweir         if ( xId2.is() )
1959cdf0e10cSrcweir             xSource = queryContent( xId2 );
1960cdf0e10cSrcweir     }
1961cdf0e10cSrcweir     catch ( ucb::IllegalIdentifierException const & )
1962cdf0e10cSrcweir     {
1963cdf0e10cSrcweir         // Error handling via "if ( !xSource.is() )" below.
1964cdf0e10cSrcweir     }
1965cdf0e10cSrcweir 
1966cdf0e10cSrcweir     if ( !xSource.is() )
1967cdf0e10cSrcweir     {
1968cdf0e10cSrcweir         uno::Any aProps
1969cdf0e10cSrcweir             = uno::makeAny(beans::PropertyValue(
1970cdf0e10cSrcweir                                   rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1971cdf0e10cSrcweir                                                     "Uri")),
1972cdf0e10cSrcweir                                   -1,
1973cdf0e10cSrcweir                                   uno::makeAny(rArg.SourceURL),
1974cdf0e10cSrcweir                                   beans::PropertyState_DIRECT_VALUE));
1975cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
1976cdf0e10cSrcweir             ucb::IOErrorCode_CANT_READ,
1977cdf0e10cSrcweir             uno::Sequence< uno::Any >(&aProps, 1),
1978cdf0e10cSrcweir             xEnv,
1979cdf0e10cSrcweir             rtl::OUString::createFromAscii(
1980cdf0e10cSrcweir                 "Can't instanciate source object!" ),
1981cdf0e10cSrcweir             this );
1982cdf0e10cSrcweir         // Unreachable
1983cdf0e10cSrcweir     }
1984cdf0e10cSrcweir 
1985cdf0e10cSrcweir     uno::Reference< ucb::XCommandProcessor > xCommandProcessor(
1986cdf0e10cSrcweir                                                 xSource, uno::UNO_QUERY );
1987cdf0e10cSrcweir     if ( !xCommandProcessor.is() )
1988cdf0e10cSrcweir     {
1989cdf0e10cSrcweir         uno::Any aProps
1990cdf0e10cSrcweir             = uno::makeAny(beans::PropertyValue(
1991cdf0e10cSrcweir                                   rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
1992cdf0e10cSrcweir                                                     "Uri")),
1993cdf0e10cSrcweir                                   -1,
1994cdf0e10cSrcweir                                   uno::makeAny(rArg.SourceURL),
1995cdf0e10cSrcweir                                   beans::PropertyState_DIRECT_VALUE));
1996cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
1997cdf0e10cSrcweir             ucb::IOErrorCode_CANT_READ,
1998cdf0e10cSrcweir             uno::Sequence< uno::Any >(&aProps, 1),
1999cdf0e10cSrcweir             xEnv,
2000cdf0e10cSrcweir             rtl::OUString::createFromAscii(
2001cdf0e10cSrcweir                 "Source content is not a XCommandProcessor!" ),
2002cdf0e10cSrcweir             this );
2003cdf0e10cSrcweir         // Unreachable
2004cdf0e10cSrcweir     }
2005cdf0e10cSrcweir 
2006cdf0e10cSrcweir     // Obtain interesting property values from source...
2007cdf0e10cSrcweir 
2008cdf0e10cSrcweir     uno::Sequence< beans::Property > aProps( 4 );
2009cdf0e10cSrcweir 
2010cdf0e10cSrcweir     aProps[ 0 ].Name   = rtl::OUString::createFromAscii( "IsFolder" );
2011cdf0e10cSrcweir     aProps[ 0 ].Handle = -1; /* unknown */
2012cdf0e10cSrcweir     aProps[ 1 ].Name   = rtl::OUString::createFromAscii( "IsDocument" );
2013cdf0e10cSrcweir     aProps[ 1 ].Handle = -1; /* unknown */
2014cdf0e10cSrcweir     aProps[ 2 ].Name   = rtl::OUString::createFromAscii( "TargetURL" );
2015cdf0e10cSrcweir     aProps[ 2 ].Handle = -1; /* unknown */
2016cdf0e10cSrcweir     aProps[ 3 ].Name   = rtl::OUString::createFromAscii( "BaseURI" );
2017cdf0e10cSrcweir     aProps[ 3 ].Handle = -1; /* unknown */
2018cdf0e10cSrcweir 
2019cdf0e10cSrcweir     ucb::Command aGetPropsCommand(
2020cdf0e10cSrcweir                 rtl::OUString::createFromAscii( "getPropertyValues" ),
2021cdf0e10cSrcweir                 -1,
2022cdf0e10cSrcweir                 uno::makeAny( aProps ) );
2023cdf0e10cSrcweir 
2024cdf0e10cSrcweir     uno::Reference< sdbc::XRow > xRow;
2025cdf0e10cSrcweir     xCommandProcessor->execute( aGetPropsCommand, 0, xLocalEnv ) >>= xRow;
2026cdf0e10cSrcweir 
2027cdf0e10cSrcweir     if ( !xRow.is() )
2028cdf0e10cSrcweir     {
2029cdf0e10cSrcweir         uno::Any aProps2
2030cdf0e10cSrcweir             = uno::makeAny(beans::PropertyValue(
2031cdf0e10cSrcweir                                   rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
2032cdf0e10cSrcweir                                                     "Uri")),
2033cdf0e10cSrcweir                                   -1,
2034cdf0e10cSrcweir                                   uno::makeAny(rArg.SourceURL),
2035cdf0e10cSrcweir                                   beans::PropertyState_DIRECT_VALUE));
2036cdf0e10cSrcweir         ucbhelper::cancelCommandExecution(
2037cdf0e10cSrcweir             ucb::IOErrorCode_CANT_READ,
2038cdf0e10cSrcweir             uno::Sequence< uno::Any >(&aProps2, 1),
2039cdf0e10cSrcweir             xEnv,
2040cdf0e10cSrcweir             rtl::OUString::createFromAscii(
2041cdf0e10cSrcweir                 "Unable to get properties from source object!" ),
2042cdf0e10cSrcweir             this );
2043cdf0e10cSrcweir         // Unreachable
2044cdf0e10cSrcweir     }
2045cdf0e10cSrcweir 
2046cdf0e10cSrcweir     TransferCommandContext aTransferCtx(
2047cdf0e10cSrcweir         m_xSMgr, this, xLocalEnv, xEnv, rArg );
2048cdf0e10cSrcweir 
2049cdf0e10cSrcweir     if ( rArg.NewTitle.getLength() == 0 )
2050cdf0e10cSrcweir     {
2051cdf0e10cSrcweir         // BaseURI: property is optional.
2052cdf0e10cSrcweir         rtl::OUString aBaseURI( xRow->getString( 4 ) );
2053cdf0e10cSrcweir         if ( aBaseURI.getLength() )
2054cdf0e10cSrcweir         {
2055cdf0e10cSrcweir             aTransferCtx.aArg.NewTitle
2056cdf0e10cSrcweir                 = createDesiredName( aBaseURI, rtl::OUString() );
2057cdf0e10cSrcweir         }
2058cdf0e10cSrcweir     }
2059cdf0e10cSrcweir 
2060cdf0e10cSrcweir     // Do it!
2061cdf0e10cSrcweir     globalTransfer_( aTransferCtx, xSource, xTarget, xRow );
2062cdf0e10cSrcweir 
2063cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
2064cdf0e10cSrcweir     //
2065cdf0e10cSrcweir     // (3) Delete source, if operation is MOVE.
2066cdf0e10cSrcweir     //
2067cdf0e10cSrcweir     //////////////////////////////////////////////////////////////////////
2068cdf0e10cSrcweir 
2069cdf0e10cSrcweir     if ( rArg.Operation == ucb::TransferCommandOperation_MOVE )
2070cdf0e10cSrcweir     {
2071cdf0e10cSrcweir         try
2072cdf0e10cSrcweir         {
2073cdf0e10cSrcweir             ucb::Command aCommand(
2074cdf0e10cSrcweir                 rtl::OUString::createFromAscii( "delete" ), // Name
2075cdf0e10cSrcweir                 -1,                                         // Handle
2076cdf0e10cSrcweir                 uno::makeAny( sal_Bool( sal_True ) ) );     // Argument
2077cdf0e10cSrcweir 
2078cdf0e10cSrcweir             xCommandProcessor->execute( aCommand, 0, xLocalEnv );
2079cdf0e10cSrcweir         }
2080cdf0e10cSrcweir         catch ( uno::Exception const & )
2081cdf0e10cSrcweir         {
2082cdf0e10cSrcweir             OSL_ENSURE( sal_False, "Cannot delete source object!" );
2083cdf0e10cSrcweir             throw;
2084cdf0e10cSrcweir         }
2085cdf0e10cSrcweir     }
2086cdf0e10cSrcweir }
2087