xref: /trunk/main/ucbhelper/source/client/content.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_ucbhelper.hxx"
30 
31 /**************************************************************************
32                                 TODO
33  **************************************************************************
34 
35  *************************************************************************/
36 #include <osl/diagnose.h>
37 #include <osl/mutex.hxx>
38 #include <salhelper/simplereferenceobject.hxx>
39 #include <cppuhelper/weak.hxx>
40 
41 #include <cppuhelper/implbase1.hxx>
42 #include <com/sun/star/ucb/ContentCreationError.hpp>
43 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
44 #include <com/sun/star/ucb/XCommandInfo.hpp>
45 #include <com/sun/star/ucb/XCommandProcessor.hpp>
46 #include <com/sun/star/ucb/Command.hpp>
47 #include <com/sun/star/ucb/CommandInfo.hpp>
48 #include <com/sun/star/ucb/ContentAction.hpp>
49 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
50 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
51 #include <com/sun/star/ucb/GlobalTransferCommandArgument.hpp>
52 #include <com/sun/star/ucb/NameClash.hpp>
53 #include <com/sun/star/ucb/OpenMode.hpp>
54 #include <com/sun/star/ucb/XContentCreator.hpp>
55 #include <com/sun/star/ucb/XContentEventListener.hpp>
56 #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
57 #include <com/sun/star/ucb/XContentProvider.hpp>
58 #include <com/sun/star/ucb/XContentProviderManager.hpp>
59 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
60 #include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp>
61 #include <com/sun/star/beans/XPropertySetInfo.hpp>
62 #include <com/sun/star/beans/Property.hpp>
63 #include <com/sun/star/beans/PropertyValue.hpp>
64 #include <com/sun/star/sdbc/XResultSet.hpp>
65 #include <com/sun/star/sdbc/XRow.hpp>
66 #include <com/sun/star/lang/IllegalArgumentException.hpp>
67 #include <com/sun/star/beans/UnknownPropertyException.hpp>
68 #include <ucbhelper/macros.hxx>
69 #include <ucbhelper/content.hxx>
70 #include <ucbhelper/contentbroker.hxx>
71 #include <ucbhelper/activedatasink.hxx>
72 #include <ucbhelper/activedatastreamer.hxx>
73 #include <ucbhelper/interactionrequest.hxx>
74 #include <ucbhelper/cancelcommandexecution.hxx>
75 
76 using namespace com::sun::star::container;
77 using namespace com::sun::star::beans;
78 using namespace com::sun::star::io;
79 using namespace com::sun::star::lang;
80 using namespace com::sun::star::sdbc;
81 using namespace com::sun::star::task;
82 using namespace com::sun::star::ucb;
83 using namespace com::sun::star::uno;
84 
85 namespace ucbhelper
86 {
87 
88 class EmptyInputStream : public ::cppu::WeakImplHelper1< XInputStream >
89 {
90 public:
91     virtual sal_Int32 SAL_CALL readBytes(
92         Sequence< sal_Int8 > & data, sal_Int32 nBytesToRead )
93         throw (IOException, RuntimeException);
94     virtual sal_Int32 SAL_CALL readSomeBytes(
95         Sequence< sal_Int8 > & data, sal_Int32 nMaxBytesToRead )
96         throw (IOException, RuntimeException);
97     virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
98         throw (IOException, RuntimeException);
99     virtual sal_Int32 SAL_CALL available()
100         throw (IOException, RuntimeException);
101     virtual void SAL_CALL closeInput()
102         throw (IOException, RuntimeException);
103 };
104 
105 sal_Int32 EmptyInputStream::readBytes(
106     Sequence< sal_Int8 > & data, sal_Int32 )
107     throw (IOException, RuntimeException)
108 {
109     data.realloc( 0 );
110     return 0;
111 }
112 
113 sal_Int32 EmptyInputStream::readSomeBytes(
114     Sequence< sal_Int8 > & data, sal_Int32 )
115     throw (IOException, RuntimeException)
116 {
117     data.realloc( 0 );
118     return 0;
119 }
120 
121 void EmptyInputStream::skipBytes( sal_Int32 )
122     throw (IOException, RuntimeException)
123 {
124 }
125 
126 sal_Int32 EmptyInputStream::available()
127     throw (IOException, RuntimeException)
128 {
129     return 0;
130 }
131 
132 void EmptyInputStream::closeInput()
133     throw (IOException, RuntimeException)
134 {
135 }
136 
137 
138 //=========================================================================
139 //=========================================================================
140 //
141 // class ContentEventListener_Impl.
142 //
143 //=========================================================================
144 //=========================================================================
145 
146 class ContentEventListener_Impl : public cppu::OWeakObject,
147                                       public XContentEventListener
148 {
149     Content_Impl& m_rContent;
150 
151 public:
152     ContentEventListener_Impl( Content_Impl& rContent )
153     : m_rContent( rContent ) {}
154 
155     // XInterface
156     XINTERFACE_DECL()
157 
158     // XContentEventListener
159     virtual void SAL_CALL contentEvent( const ContentEvent& evt )
160         throw( RuntimeException );
161 
162     // XEventListener ( base of XContentEventListener )
163     virtual void SAL_CALL disposing( const EventObject& Source )
164         throw( RuntimeException );
165 };
166 
167 //=========================================================================
168 //=========================================================================
169 //
170 // class Content_Impl.
171 //
172 //=========================================================================
173 //=========================================================================
174 
175 class Content_Impl : public salhelper::SimpleReferenceObject
176 {
177 friend class ContentEventListener_Impl;
178 
179     mutable rtl::OUString               m_aURL;
180     Reference< XMultiServiceFactory >   m_xSMgr;
181     Reference< XContent >               m_xContent;
182     Reference< XCommandProcessor >          m_xCommandProcessor;
183     Reference< XCommandEnvironment >    m_xEnv;
184     Reference< XContentEventListener >  m_xContentEventListener;
185     mutable osl::Mutex                  m_aMutex;
186     sal_Int32                           m_nCommandId;
187 
188 private:
189     void reinit( const Reference< XContent >& xContent );
190     void disposing(const EventObject& Source);
191 
192 public:
193     Content_Impl() : m_nCommandId( 0 ) {};
194     Content_Impl( const Reference< XMultiServiceFactory >& rSMgr,
195                   const Reference< XContent >& rContent,
196                   const Reference< XCommandEnvironment >& rEnv );
197 
198     virtual ~Content_Impl();
199 
200     const rtl::OUString&           getURL() const;
201     Reference< XContent >          getContent();
202     Reference< XCommandProcessor > getCommandProcessor();
203     sal_Int32 getCommandId();
204     Reference< XMultiServiceFactory > getServiceManager() { return m_xSMgr; }
205 
206     Any  executeCommand( const Command& rCommand );
207     void abortCommand();
208 
209     inline const Reference< XCommandEnvironment >& getEnvironment() const;
210     inline void setEnvironment(
211                         const Reference< XCommandEnvironment >& xNewEnv );
212 
213     void inserted();
214 };
215 
216 //=========================================================================
217 // Helpers.
218 //=========================================================================
219 
220 static void ensureContentProviderForURL( const ContentBroker & rBroker,
221                                          const rtl::OUString & rURL )
222     throw ( ContentCreationException, RuntimeException )
223 {
224     Reference< XContentProviderManager > xMgr
225         = rBroker.getContentProviderManagerInterface();
226     if ( !xMgr.is() )
227     {
228         throw RuntimeException(
229             rtl::OUString::createFromAscii(
230                 "UCB does not implement mandatory interface "
231                 "XContentProviderManager!" ),
232             Reference< XInterface >() );
233     }
234     else
235     {
236         Reference< XContentProvider > xProv
237             = xMgr->queryContentProvider( rURL );
238         if ( !xProv.is() )
239         {
240             throw ContentCreationException(
241                 rtl::OUString::createFromAscii(
242                     "No Content Provider available for given URL!" ),
243                 Reference< XInterface >(),
244                 ContentCreationError_NO_CONTENT_PROVIDER );
245         }
246     }
247 }
248 
249 //=========================================================================
250 static ContentBroker* getContentBroker( bool bThrow )
251     throw ( ContentCreationException, RuntimeException )
252 {
253     ContentBroker* pBroker = ContentBroker::get();
254 
255     if ( !pBroker )
256     {
257         if ( bThrow )
258             throw RuntimeException(
259                     rtl::OUString::createFromAscii( "No Content Broker!" ),
260                     Reference< XInterface >() );
261     }
262     else
263     {
264 #if OSL_DEBUG_LEVEL > 1
265         Reference< XContentProviderManager > xMgr
266             = pBroker->getContentProviderManagerInterface();
267         if ( !xMgr.is() )
268         {
269             if ( bThrow )
270                 throw RuntimeException(
271                         rtl::OUString::createFromAscii(
272                             "UCB does not implement mandatory interface "
273                             "XContentProviderManager!" ),
274                         Reference< XInterface >() );
275         }
276         else
277         {
278             OSL_ENSURE( xMgr->queryContentProviders().getLength(),
279                         "Content Broker not configured (no providers)!" );
280         }
281 #endif
282     }
283 
284     return pBroker;
285 }
286 
287 //=========================================================================
288 static Reference< XContentIdentifier > getContentIdentifier(
289                                     const ContentBroker & rBroker,
290                                     const rtl::OUString & rURL,
291                                     bool bThrow )
292     throw ( ContentCreationException, RuntimeException )
293 {
294     Reference< XContentIdentifierFactory > xIdFac
295                         = rBroker.getContentIdentifierFactoryInterface();
296     if ( xIdFac.is() )
297     {
298         Reference< XContentIdentifier > xId
299             = xIdFac->createContentIdentifier( rURL );
300 
301         if ( xId.is() )
302             return xId;
303 
304         if ( bThrow )
305         {
306             ensureContentProviderForURL( rBroker, rURL );
307 
308             throw ContentCreationException(
309                 rtl::OUString::createFromAscii(
310                     "Unable to create Content Identifier!" ),
311                 Reference< XInterface >(),
312                 ContentCreationError_IDENTIFIER_CREATION_FAILED );
313         }
314     }
315     else
316     {
317         if ( bThrow )
318             throw RuntimeException(
319                     rtl::OUString::createFromAscii(
320                         "UCB does not implement mandatory interface "
321                         "XContentIdentifierFactory!" ),
322                     Reference< XInterface >() );
323     }
324 
325     return Reference< XContentIdentifier >();
326 }
327 
328 //=========================================================================
329 static Reference< XContent > getContent(
330                                     const ContentBroker & rBroker,
331                                     const Reference< XContentIdentifier > & xId,
332                                     bool bThrow )
333     throw ( ContentCreationException, RuntimeException )
334 {
335     Reference< XContentProvider > xProvider
336         = rBroker.getContentProviderInterface();
337     if ( xProvider.is() )
338     {
339         Reference< XContent > xContent;
340         rtl::OUString msg;
341         try
342         {
343             xContent = xProvider->queryContent( xId );
344         }
345         catch ( IllegalIdentifierException const & e )
346         {
347             msg = e.Message;
348             // handled below.
349         }
350 
351         if ( xContent.is() )
352             return xContent;
353 
354         if ( bThrow )
355         {
356             ensureContentProviderForURL( rBroker, xId->getContentIdentifier() );
357 
358             throw ContentCreationException(
359                     rtl::OUString::createFromAscii(
360                         "Unable to create Content! " ) + msg,
361                     Reference< XInterface >(),
362                     ContentCreationError_CONTENT_CREATION_FAILED );
363         }
364     }
365     else
366     {
367         if ( bThrow )
368             throw RuntimeException(
369                     rtl::OUString::createFromAscii(
370                         "UCB does not implement mandatory interface "
371                         "XContentProvider!" ),
372                     Reference< XInterface >() );
373     }
374 
375     return Reference< XContent >();
376 }
377 
378 //=========================================================================
379 //=========================================================================
380 //
381 // Content Implementation.
382 //
383 //=========================================================================
384 //=========================================================================
385 
386 Content::Content()
387 : m_xImpl( new Content_Impl )
388 {
389 }
390 
391 //=========================================================================
392 Content::Content( const rtl::OUString& rURL,
393                   const Reference< XCommandEnvironment >& rEnv )
394     throw ( ContentCreationException, RuntimeException )
395 {
396     ContentBroker* pBroker = getContentBroker( true );
397 
398     Reference< XContentIdentifier > xId
399         = getContentIdentifier( *pBroker, rURL, true );
400 
401     Reference< XContent > xContent = getContent( *pBroker, xId, true );
402 
403     m_xImpl = new Content_Impl( pBroker->getServiceManager(), xContent, rEnv );
404 }
405 
406 //=========================================================================
407 Content::Content( const Reference< XContentIdentifier >& rId,
408                   const Reference< XCommandEnvironment >& rEnv )
409     throw ( ContentCreationException, RuntimeException )
410 {
411     ContentBroker* pBroker = getContentBroker( true );
412 
413     Reference< XContent > xContent = getContent( *pBroker, rId, true );
414 
415     m_xImpl = new Content_Impl( pBroker->getServiceManager(), xContent, rEnv );
416 }
417 
418 //=========================================================================
419 Content::Content( const Reference< XContent >& rContent,
420                   const Reference< XCommandEnvironment >& rEnv )
421     throw ( ContentCreationException, RuntimeException )
422 {
423     ContentBroker* pBroker = getContentBroker( true );
424 
425     m_xImpl = new Content_Impl( pBroker->getServiceManager(), rContent, rEnv );
426 }
427 
428 //=========================================================================
429 Content::Content( const Content& rOther )
430 {
431     m_xImpl = rOther.m_xImpl;
432 }
433 
434 //=========================================================================
435 // static
436 sal_Bool Content::create( const rtl::OUString& rURL,
437                           const Reference< XCommandEnvironment >& rEnv,
438                           Content& rContent )
439 {
440     ContentBroker* pBroker = getContentBroker( false );
441     if ( !pBroker )
442         return sal_False;
443 
444     Reference< XContentIdentifier > xId
445         = getContentIdentifier( *pBroker, rURL, false );
446     if ( !xId.is() )
447         return sal_False;
448 
449     Reference< XContent > xContent = getContent( *pBroker, xId, false );
450     if ( !xContent.is() )
451         return sal_False;
452 
453     rContent.m_xImpl
454         = new Content_Impl( pBroker->getServiceManager(), xContent, rEnv );
455 
456     return sal_True;
457 }
458 
459 //=========================================================================
460 // static
461 sal_Bool Content::create( const Reference< XContentIdentifier >& rId,
462                           const Reference< XCommandEnvironment >& rEnv,
463                           Content& rContent )
464 {
465     ContentBroker* pBroker = getContentBroker( false );
466     if ( !pBroker )
467         return sal_False;
468 
469     Reference< XContent > xContent = getContent( *pBroker, rId, false );
470     if ( !xContent.is() )
471         return sal_False;
472 
473     rContent.m_xImpl
474         = new Content_Impl( pBroker->getServiceManager(), xContent, rEnv );
475 
476     return sal_True;
477 }
478 
479 //=========================================================================
480 // static
481 sal_Bool Content::create( const Reference< XContent >& xContent,
482                           const Reference< XCommandEnvironment >& rEnv,
483                           Content& rContent )
484 {
485     ContentBroker* pBroker = getContentBroker( false );
486     if ( !pBroker )
487         return sal_False;
488 
489     rContent.m_xImpl
490         = new Content_Impl( pBroker->getServiceManager(), xContent, rEnv );
491 
492     return sal_True;
493 }
494 
495 //=========================================================================
496 Content::~Content()
497 {
498 }
499 
500 //=========================================================================
501 Content& Content::operator=( const Content& rOther )
502 {
503     m_xImpl = rOther.m_xImpl;
504     return *this;
505 }
506 
507 //=========================================================================
508 Reference< XContent > Content::get() const
509 {
510     return m_xImpl->getContent();
511 }
512 
513 //=========================================================================
514 const rtl::OUString& Content::getURL() const
515 {
516     return m_xImpl->getURL();
517 }
518 
519 //=========================================================================
520 const Reference< XCommandEnvironment >& Content::getCommandEnvironment() const
521 {
522     return m_xImpl->getEnvironment();
523 }
524 
525 //=========================================================================
526 void Content::setCommandEnvironment(
527                         const Reference< XCommandEnvironment >& xNewEnv )
528 {
529     m_xImpl->setEnvironment( xNewEnv );
530 }
531 
532 //=========================================================================
533 Reference< XCommandInfo > Content::getCommands()
534     throw( CommandAbortedException, RuntimeException, Exception )
535 {
536     Command aCommand;
537     aCommand.Name     = rtl::OUString::createFromAscii( "getCommandInfo" );
538     aCommand.Handle   = -1; // n/a
539     aCommand.Argument = Any();
540 
541     Any aResult = m_xImpl->executeCommand( aCommand );
542 
543     Reference< XCommandInfo > xInfo;
544     aResult >>= xInfo;
545     return xInfo;
546 }
547 
548 //=========================================================================
549 Reference< XPropertySetInfo > Content::getProperties()
550     throw( CommandAbortedException, RuntimeException, Exception )
551 {
552     Command aCommand;
553     aCommand.Name     = rtl::OUString::createFromAscii( "getPropertySetInfo" );
554     aCommand.Handle   = -1; // n/a
555     aCommand.Argument = Any();
556 
557     Any aResult = m_xImpl->executeCommand( aCommand );
558 
559     Reference< XPropertySetInfo > xInfo;
560     aResult >>= xInfo;
561     return xInfo;
562 }
563 
564 //=========================================================================
565 Any Content::getPropertyValue( const rtl::OUString& rPropertyName )
566     throw( CommandAbortedException, RuntimeException, Exception )
567 {
568     Sequence< rtl::OUString > aNames( 1 );
569     aNames.getArray()[ 0 ] = rPropertyName;
570 
571     Sequence< Any > aRet = getPropertyValues( aNames );
572     return aRet.getConstArray()[ 0 ];
573 }
574 
575 //=========================================================================
576 Any Content::getPropertyValue( sal_Int32 nPropertyHandle )
577     throw( CommandAbortedException, RuntimeException, Exception )
578 {
579     Sequence< sal_Int32 > aHandles( 1 );
580     aHandles.getArray()[ 0 ] = nPropertyHandle;
581 
582     Sequence< Any > aRet = getPropertyValues( aHandles );
583     return aRet.getConstArray()[ 0 ];
584 }
585 
586 //=========================================================================
587 Any Content::setPropertyValue( const rtl::OUString& rName,
588                                 const Any& rValue )
589     throw( CommandAbortedException, RuntimeException, Exception )
590 {
591     Sequence< rtl::OUString > aNames( 1 );
592     aNames.getArray()[ 0 ] = rName;
593 
594     Sequence< Any > aValues( 1 );
595     aValues.getArray()[ 0 ] = rValue;
596 
597     Sequence< Any > aErrors = setPropertyValues( aNames, aValues );
598     return aErrors.getConstArray()[ 0 ];
599 }
600 
601 //=========================================================================
602 Any Content::setPropertyValue( const sal_Int32 nPropertyHandle,
603                                 const Any& rValue )
604     throw( CommandAbortedException, RuntimeException, Exception )
605 {
606     Sequence< sal_Int32 > aHandles( 1 );
607     aHandles.getArray()[ 0 ] = nPropertyHandle;
608 
609     Sequence< Any > aValues( 1 );
610     aValues.getArray()[ 0 ] = rValue;
611 
612     Sequence< Any > aErrors = setPropertyValues( aHandles, aValues );
613     return aErrors.getConstArray()[ 0 ];
614 }
615 
616 //=========================================================================
617 Sequence< Any > Content::getPropertyValues(
618                             const Sequence< rtl::OUString >& rPropertyNames )
619     throw( CommandAbortedException, RuntimeException, Exception )
620 {
621     Reference< XRow > xRow = getPropertyValuesInterface( rPropertyNames );
622 
623     sal_Int32 nCount = rPropertyNames.getLength();
624     Sequence< Any > aValues( nCount );
625 
626     if ( xRow.is() )
627     {
628         Any* pValues = aValues.getArray();
629 
630         for ( sal_Int32 n = 0; n < nCount; ++n )
631             pValues[ n ] = xRow->getObject( n + 1, Reference< XNameAccess >() );
632     }
633 
634     return aValues;
635 }
636 
637 //=========================================================================
638 Sequence< Any > Content::getPropertyValues(
639                             const Sequence< sal_Int32 >& nPropertyHandles )
640     throw( CommandAbortedException, RuntimeException, Exception )
641 {
642     Reference< XRow > xRow = getPropertyValuesInterface( nPropertyHandles );
643 
644     sal_Int32 nCount = nPropertyHandles.getLength();
645     Sequence< Any > aValues( nCount );
646 
647     if ( xRow.is() )
648     {
649         Any* pValues = aValues.getArray();
650 
651         for ( sal_Int32 n = 0; n < nCount; ++n )
652             pValues[ n ] = xRow->getObject( n + 1, Reference< XNameAccess >() );
653     }
654 
655     return aValues;
656 }
657 
658 //=========================================================================
659 Reference< XRow > Content::getPropertyValuesInterface(
660                             const Sequence< rtl::OUString >& rPropertyNames )
661     throw( CommandAbortedException, RuntimeException, Exception )
662 {
663     sal_Int32 nCount = rPropertyNames.getLength();
664     Sequence< Property > aProps( nCount );
665     Property* pProps = aProps.getArray();
666 
667     const rtl::OUString* pNames  = rPropertyNames.getConstArray();
668 
669     for ( sal_Int32 n = 0; n< nCount; ++n )
670     {
671         Property& rProp = pProps[ n ];
672 
673         rProp.Name       = pNames[ n ];
674         rProp.Handle     = -1; // n/a
675 //        rProp.Type       =
676 //        rProp.Attributes = ;
677     }
678 
679     Command aCommand;
680     aCommand.Name     = rtl::OUString::createFromAscii( "getPropertyValues" );
681     aCommand.Handle   = -1; // n/a
682     aCommand.Argument <<= aProps;
683 
684     Any aResult = m_xImpl->executeCommand( aCommand );
685 
686     Reference< XRow > xRow;
687     aResult >>= xRow;
688     return xRow;
689 }
690 
691 //=========================================================================
692 Reference< XRow > Content::getPropertyValuesInterface(
693                             const Sequence< sal_Int32 >& nPropertyHandles )
694     throw( CommandAbortedException, RuntimeException, Exception )
695 {
696     sal_Int32 nCount = nPropertyHandles.getLength();
697     Sequence< Property > aProps( nCount );
698     Property* pProps = aProps.getArray();
699 
700     const sal_Int32* pHandles  = nPropertyHandles.getConstArray();
701 
702     for ( sal_Int32 n = 0; n< nCount; ++n )
703     {
704         Property& rProp = pProps[ n ];
705 
706         rProp.Name       = rtl::OUString(); // n/a
707         rProp.Handle     = pHandles[ n ];
708 //        rProp.Type       =
709 //        rProp.Attributes = ;
710     }
711 
712     Command aCommand;
713     aCommand.Name     = rtl::OUString::createFromAscii( "getPropertyValues" );
714     aCommand.Handle   = -1; // n/a
715     aCommand.Argument <<= aProps;
716 
717     Any aResult = m_xImpl->executeCommand( aCommand );
718 
719     Reference< XRow > xRow;
720     aResult >>= xRow;
721     return xRow;
722 }
723 
724 //=========================================================================
725 Sequence< Any > Content::setPropertyValues(
726                             const Sequence< rtl::OUString >& rPropertyNames,
727                                 const Sequence< Any >& rValues )
728     throw( CommandAbortedException, RuntimeException, Exception )
729 {
730     if ( rPropertyNames.getLength() != rValues.getLength() )
731     {
732         ucbhelper::cancelCommandExecution(
733             makeAny( IllegalArgumentException(
734                         rtl::OUString::createFromAscii(
735                             "Length of property names sequence and value "
736                             "sequence are unequal!" ),
737                         get(),
738                         -1 ) ),
739             m_xImpl->getEnvironment() );
740         // Unreachable
741     }
742 
743     sal_Int32 nCount = rValues.getLength();
744     Sequence< PropertyValue > aProps( nCount );
745     PropertyValue* pProps = aProps.getArray();
746 
747     const rtl::OUString* pNames  = rPropertyNames.getConstArray();
748     const Any* pValues = rValues.getConstArray();
749 
750     for ( sal_Int32 n = 0; n< nCount; ++n )
751     {
752         PropertyValue& rProp = pProps[ n ];
753 
754         rProp.Name   = pNames[ n ];
755         rProp.Handle = -1; // n/a
756         rProp.Value  = pValues[ n ];
757 //        rProp.State  = ;
758     }
759 
760     Command aCommand;
761     aCommand.Name     = rtl::OUString::createFromAscii( "setPropertyValues" );
762     aCommand.Handle   = -1; // n/a
763     aCommand.Argument <<= aProps;
764 
765     Any aResult = m_xImpl->executeCommand( aCommand );
766 
767     Sequence< Any > aErrors;
768     aResult >>= aErrors;
769     return aErrors;
770 }
771 
772 //=========================================================================
773 Sequence< Any > Content::setPropertyValues(
774                             const Sequence< sal_Int32 >& nPropertyHandles,
775                                 const Sequence< Any >& rValues )
776     throw( CommandAbortedException, RuntimeException, Exception )
777 {
778     if ( nPropertyHandles.getLength() != rValues.getLength() )
779     {
780         ucbhelper::cancelCommandExecution(
781             makeAny( IllegalArgumentException(
782                         rtl::OUString::createFromAscii(
783                             "Length of property handles sequence and value "
784                             "sequence are unequal!" ),
785                         get(),
786                         -1 ) ),
787             m_xImpl->getEnvironment() );
788         // Unreachable
789     }
790 
791     sal_Int32 nCount = rValues.getLength();
792     Sequence< PropertyValue > aProps( nCount );
793     PropertyValue* pProps = aProps.getArray();
794 
795     const sal_Int32* pHandles = nPropertyHandles.getConstArray();
796     const Any*       pValues  = rValues.getConstArray();
797 
798     for ( sal_Int32 n = 0; n< nCount; ++n )
799     {
800         PropertyValue& rProp = pProps[ n ];
801 
802         rProp.Name   = rtl::OUString(); // n/a
803         rProp.Handle = pHandles[ n ];
804         rProp.Value  = pValues[ n ];
805 //        rProp.State  = ;
806     }
807 
808     Command aCommand;
809     aCommand.Name     = rtl::OUString::createFromAscii( "setPropertyValues" );
810     aCommand.Handle   = -1; // n/a
811     aCommand.Argument <<= aProps;
812 
813     Any aResult = m_xImpl->executeCommand( aCommand );
814 
815     Sequence< Any > aErrors;
816     aResult >>= aErrors;
817     return aErrors;
818 }
819 
820 //=========================================================================
821 Any Content::executeCommand( const rtl::OUString& rCommandName,
822                              const Any& rCommandArgument )
823     throw( CommandAbortedException, RuntimeException, Exception )
824 {
825     Command aCommand;
826     aCommand.Name     = rCommandName;
827     aCommand.Handle   = -1; // n/a
828     aCommand.Argument = rCommandArgument;
829 
830     return m_xImpl->executeCommand( aCommand );
831 }
832 
833 //=========================================================================
834 Any Content::executeCommand( sal_Int32 nCommandHandle,
835                              const Any& rCommandArgument )
836     throw( CommandAbortedException, RuntimeException, Exception )
837 {
838     Command aCommand;
839     aCommand.Name     = rtl::OUString(); // n/a
840     aCommand.Handle   = nCommandHandle;
841     aCommand.Argument = rCommandArgument;
842 
843     return m_xImpl->executeCommand( aCommand );
844 }
845 
846 //=========================================================================
847 void Content::abortCommand()
848 {
849     m_xImpl->abortCommand();
850 }
851 
852 //=========================================================================
853 Any Content::createCursorAny( const Sequence< rtl::OUString >& rPropertyNames,
854                               ResultSetInclude eMode )
855     throw( CommandAbortedException, RuntimeException, Exception )
856 {
857     sal_Int32 nCount = rPropertyNames.getLength();
858     Sequence< Property > aProps( nCount );
859     Property* pProps = aProps.getArray();
860     const rtl::OUString* pNames = rPropertyNames.getConstArray();
861     for ( sal_Int32 n = 0; n < nCount; ++n )
862     {
863         Property& rProp = pProps[ n ];
864         rProp.Name   = pNames[ n ];
865         rProp.Handle = -1; // n/a
866     }
867 
868     OpenCommandArgument2 aArg;
869     aArg.Mode       = ( eMode == INCLUDE_FOLDERS_ONLY )
870                         ? OpenMode::FOLDERS
871                         : ( eMode == INCLUDE_DOCUMENTS_ONLY )
872                             ? OpenMode::DOCUMENTS : OpenMode::ALL;
873     aArg.Priority   = 0; // unused
874     aArg.Sink       = Reference< XInterface >(); // unused
875     aArg.Properties = aProps;
876 
877     Command aCommand;
878     aCommand.Name     = rtl::OUString::createFromAscii( "open" );
879     aCommand.Handle   = -1; // n/a
880     aCommand.Argument <<= aArg;
881 
882     return m_xImpl->executeCommand( aCommand );
883 }
884 
885 //=========================================================================
886 Any Content::createCursorAny( const Sequence< sal_Int32 >& rPropertyHandles,
887                               ResultSetInclude eMode )
888     throw( CommandAbortedException, RuntimeException, Exception )
889 {
890     sal_Int32 nCount = rPropertyHandles.getLength();
891     Sequence< Property > aProps( nCount );
892     Property* pProps = aProps.getArray();
893     const sal_Int32* pHandles = rPropertyHandles.getConstArray();
894     for ( sal_Int32 n = 0; n < nCount; ++n )
895     {
896         Property& rProp = pProps[ n ];
897         rProp.Name   = rtl::OUString(); // n/a
898         rProp.Handle = pHandles[ n ];
899     }
900 
901     OpenCommandArgument2 aArg;
902     aArg.Mode       = ( eMode == INCLUDE_FOLDERS_ONLY )
903                         ? OpenMode::FOLDERS
904                         : ( eMode == INCLUDE_DOCUMENTS_ONLY )
905                             ? OpenMode::DOCUMENTS : OpenMode::ALL;
906     aArg.Priority   = 0; // unused
907     aArg.Sink       = Reference< XInterface >(); // unused
908     aArg.Properties = aProps;
909 
910     Command aCommand;
911     aCommand.Name     = rtl::OUString::createFromAscii( "open" );
912     aCommand.Handle   = -1; // n/a
913     aCommand.Argument <<= aArg;
914 
915     return m_xImpl->executeCommand( aCommand );
916 }
917 
918 //=========================================================================
919 Reference< XResultSet > Content::createCursor(
920                             const Sequence< rtl::OUString >& rPropertyNames,
921                             ResultSetInclude eMode )
922     throw( CommandAbortedException, RuntimeException, Exception )
923 {
924     Any aCursorAny = createCursorAny( rPropertyNames, eMode );
925 
926     Reference< XDynamicResultSet > xDynSet;
927     Reference< XResultSet > aResult;
928 
929     aCursorAny >>= xDynSet;
930     if ( xDynSet.is() )
931         aResult = xDynSet->getStaticResultSet();
932 
933     OSL_ENSURE( aResult.is(), "Content::createCursor - no cursor!" );
934 
935     if ( !aResult.is() )
936     {
937         // Former, the open command directly returned a XResultSet.
938         aCursorAny >>= aResult;
939 
940         OSL_ENSURE( !aResult.is(),
941                     "Content::createCursor - open-Command must "
942                     "return a Reference< XDynnamicResultSet >!" );
943     }
944 
945     return aResult;
946 }
947 
948 //=========================================================================
949 Reference< XResultSet > Content::createCursor(
950                             const Sequence< sal_Int32 >& rPropertyHandles,
951                             ResultSetInclude eMode )
952     throw( CommandAbortedException, RuntimeException, Exception )
953 {
954     Any aCursorAny = createCursorAny( rPropertyHandles, eMode );
955 
956     Reference< XDynamicResultSet > xDynSet;
957     Reference< XResultSet > aResult;
958 
959     aCursorAny >>= xDynSet;
960     if ( xDynSet.is() )
961         aResult = xDynSet->getStaticResultSet();
962 
963     OSL_ENSURE( aResult.is(), "Content::createCursor - no cursor!" );
964 
965     if ( !aResult.is() )
966     {
967         // Former, the open command directly returned a XResultSet.
968         aCursorAny >>= aResult;
969 
970         OSL_ENSURE( !aResult.is(),
971                     "Content::createCursor - open-Command must "
972                     "return a Reference< XDynnamicResultSet >!" );
973     }
974 
975     return aResult;
976 }
977 
978 //=========================================================================
979 Reference< XDynamicResultSet > Content::createDynamicCursor(
980                             const Sequence< rtl::OUString >& rPropertyNames,
981                             ResultSetInclude eMode )
982     throw( CommandAbortedException, RuntimeException, Exception )
983 {
984     Reference< XDynamicResultSet > aResult;
985     createCursorAny( rPropertyNames, eMode ) >>= aResult;
986 
987     OSL_ENSURE( aResult.is(), "Content::createDynamicCursor - no cursor!" );
988 
989     return aResult;
990 }
991 
992 //=========================================================================
993 Reference< XDynamicResultSet > Content::createDynamicCursor(
994                             const Sequence< sal_Int32 >& rPropertyHandles,
995                             ResultSetInclude eMode )
996     throw( CommandAbortedException, RuntimeException, Exception )
997 {
998     Reference< XDynamicResultSet > aResult;
999     createCursorAny( rPropertyHandles, eMode ) >>= aResult;
1000 
1001     OSL_ENSURE( aResult.is(), "Content::createDynamicCursor - no cursor!" );
1002 
1003     return aResult;
1004 }
1005 
1006 //=========================================================================
1007 Reference< XDynamicResultSet > Content::createSortedDynamicCursor(
1008                             const Sequence< rtl::OUString >& rPropertyNames,
1009                             const Sequence< NumberedSortingInfo >& rSortInfo,
1010                             Reference< XAnyCompareFactory > rAnyCompareFactory,
1011                             ResultSetInclude eMode )
1012     throw( CommandAbortedException, RuntimeException, Exception )
1013 {
1014     Reference< XDynamicResultSet > aResult;
1015     Reference< XDynamicResultSet > aOrigCursor = createDynamicCursor( rPropertyNames, eMode );
1016 
1017     if( aOrigCursor.is() )
1018     {
1019         Reference< XMultiServiceFactory > aServiceManager = m_xImpl->getServiceManager();
1020 
1021         if( aServiceManager.is() )
1022         {
1023             Reference< XSortedDynamicResultSetFactory > aSortFactory( aServiceManager->createInstance(
1024                                 rtl::OUString::createFromAscii( "com.sun.star.ucb.SortedDynamicResultSetFactory" )),
1025                                 UNO_QUERY );
1026 
1027             aResult = aSortFactory->createSortedDynamicResultSet( aOrigCursor,
1028                                                               rSortInfo,
1029                                                               rAnyCompareFactory );
1030         }
1031 
1032         OSL_ENSURE( aResult.is(), "Content::createSortedDynamicCursor - no sorted cursor!\n" );
1033 
1034         if( !aResult.is() )
1035             aResult = aOrigCursor;
1036     }
1037 
1038     return aResult;
1039 }
1040 
1041 //=========================================================================
1042 Reference< XDynamicResultSet > Content::createSortedDynamicCursor(
1043                             const Sequence< sal_Int32 >& rPropertyHandles,
1044                             const Sequence< NumberedSortingInfo >& rSortInfo,
1045                             Reference< XAnyCompareFactory > rAnyCompareFactory,
1046                             ResultSetInclude eMode )
1047     throw( CommandAbortedException, RuntimeException, Exception )
1048 {
1049     Reference< XDynamicResultSet > aResult;
1050     Reference< XDynamicResultSet > aOrigCursor = createDynamicCursor( rPropertyHandles, eMode );
1051 
1052     if( aOrigCursor.is() )
1053     {
1054         Reference< XMultiServiceFactory > aServiceManager = m_xImpl->getServiceManager();
1055 
1056         if( aServiceManager.is() )
1057         {
1058             Reference< XSortedDynamicResultSetFactory > aSortFactory( aServiceManager->createInstance(
1059                                 rtl::OUString::createFromAscii( "com.sun.star.ucb.SortedDynamicResultSetFactory" )),
1060                                 UNO_QUERY );
1061 
1062             aResult = aSortFactory->createSortedDynamicResultSet( aOrigCursor,
1063                                                               rSortInfo,
1064                                                               rAnyCompareFactory );
1065         }
1066 
1067         OSL_ENSURE( aResult.is(), "Content::createSortedDynamicCursor - no sorted cursor!\n" );
1068 
1069         if( !aResult.is() )
1070             aResult = aOrigCursor;
1071     }
1072 
1073     return aResult;
1074 }
1075 
1076 //=========================================================================
1077 Reference< XResultSet > Content::createSortedCursor(
1078                             const Sequence< rtl::OUString >& rPropertyNames,
1079                             const Sequence< NumberedSortingInfo >& rSortInfo,
1080                             Reference< XAnyCompareFactory > rAnyCompareFactory,
1081                             ResultSetInclude eMode )
1082     throw( CommandAbortedException, RuntimeException, Exception )
1083 {
1084     Reference< XResultSet > aResult;
1085     Reference< XDynamicResultSet > aDynSet;
1086 
1087     Any aCursorAny = createCursorAny( rPropertyNames, eMode );
1088 
1089     aCursorAny >>= aDynSet;
1090 
1091     if( aDynSet.is() )
1092     {
1093         Reference< XDynamicResultSet > aDynResult;
1094         Reference< XMultiServiceFactory > aServiceManager = m_xImpl->getServiceManager();
1095 
1096         if( aServiceManager.is() )
1097         {
1098             Reference< XSortedDynamicResultSetFactory > aSortFactory( aServiceManager->createInstance(
1099                                 rtl::OUString::createFromAscii( "com.sun.star.ucb.SortedDynamicResultSetFactory" )),
1100                                 UNO_QUERY );
1101 
1102             aDynResult = aSortFactory->createSortedDynamicResultSet( aDynSet,
1103                                                               rSortInfo,
1104                                                               rAnyCompareFactory );
1105         }
1106 
1107         OSL_ENSURE( aDynResult.is(), "Content::createSortedCursor - no sorted cursor!\n" );
1108 
1109         if( aDynResult.is() )
1110             aResult = aDynResult->getStaticResultSet();
1111         else
1112             aResult = aDynSet->getStaticResultSet();
1113     }
1114 
1115     OSL_ENSURE( aResult.is(), "Content::createSortedCursor - no cursor!" );
1116 
1117     if ( !aResult.is() )
1118     {
1119         // Former, the open command directly returned a XResultSet.
1120         aCursorAny >>= aResult;
1121 
1122         OSL_ENSURE( !aResult.is(),
1123                     "Content::createCursor - open-Command must "
1124                     "return a Reference< XDynnamicResultSet >!" );
1125     }
1126 
1127     return aResult;
1128 }
1129 
1130 //=========================================================================
1131 Reference< XResultSet > Content::createSortedCursor(
1132                             const Sequence< sal_Int32 >& rPropertyHandles,
1133                             const Sequence< NumberedSortingInfo >& rSortInfo,
1134                             Reference< XAnyCompareFactory > rAnyCompareFactory,
1135                             ResultSetInclude eMode )
1136     throw( CommandAbortedException, RuntimeException, Exception )
1137 {
1138     Reference< XResultSet > aResult;
1139     Reference< XDynamicResultSet > aDynSet;
1140 
1141     Any aCursorAny = createCursorAny( rPropertyHandles, eMode );
1142 
1143     aCursorAny >>= aDynSet;
1144 
1145     if( aDynSet.is() )
1146     {
1147         Reference< XDynamicResultSet > aDynResult;
1148         Reference< XMultiServiceFactory > aServiceManager = m_xImpl->getServiceManager();
1149 
1150         if( aServiceManager.is() )
1151         {
1152             Reference< XSortedDynamicResultSetFactory > aSortFactory( aServiceManager->createInstance(
1153                                 rtl::OUString::createFromAscii( "com.sun.star.ucb.SortedDynamicResultSetFactory" )),
1154                                 UNO_QUERY );
1155 
1156             aDynResult = aSortFactory->createSortedDynamicResultSet( aDynSet,
1157                                                               rSortInfo,
1158                                                               rAnyCompareFactory );
1159         }
1160 
1161         OSL_ENSURE( aDynResult.is(), "Content::createSortedCursor - no sorted cursor!\n" );
1162 
1163         if( aDynResult.is() )
1164             aResult = aDynResult->getStaticResultSet();
1165         else
1166             aResult = aDynSet->getStaticResultSet();
1167     }
1168 
1169     OSL_ENSURE( aResult.is(), "Content::createSortedCursor - no cursor!" );
1170 
1171     if ( !aResult.is() )
1172     {
1173         // Former, the open command directly returned a XResultSet.
1174         aCursorAny >>= aResult;
1175 
1176         OSL_ENSURE( !aResult.is(),
1177                     "Content::createCursor - open-Command must "
1178                     "return a Reference< XDynnamicResultSet >!" );
1179     }
1180 
1181     return aResult;
1182 }
1183 
1184 //=========================================================================
1185 Reference< XInputStream > Content::openStream()
1186     throw( CommandAbortedException, RuntimeException, Exception )
1187 {
1188     if ( !isDocument() )
1189         return Reference< XInputStream >();
1190 
1191     Reference< XActiveDataSink > xSink = new ActiveDataSink;
1192 
1193     OpenCommandArgument2 aArg;
1194     aArg.Mode       = OpenMode::DOCUMENT;
1195     aArg.Priority   = 0; // unused
1196     aArg.Sink       = xSink;
1197     aArg.Properties = Sequence< Property >( 0 ); // unused
1198 
1199     Command aCommand;
1200     aCommand.Name     = rtl::OUString::createFromAscii( "open" );
1201     aCommand.Handle   = -1; // n/a
1202     aCommand.Argument <<= aArg;
1203 
1204     m_xImpl->executeCommand( aCommand );
1205 
1206     return xSink->getInputStream();
1207 }
1208 
1209 //=========================================================================
1210 Reference< XInputStream > Content::openStreamNoLock()
1211     throw( CommandAbortedException, RuntimeException, Exception )
1212 {
1213     if ( !isDocument() )
1214         return Reference< XInputStream >();
1215 
1216     Reference< XActiveDataSink > xSink = new ActiveDataSink;
1217 
1218     OpenCommandArgument2 aArg;
1219     aArg.Mode       = OpenMode::DOCUMENT_SHARE_DENY_NONE;
1220     aArg.Priority   = 0; // unused
1221     aArg.Sink       = xSink;
1222     aArg.Properties = Sequence< Property >( 0 ); // unused
1223 
1224     Command aCommand;
1225     aCommand.Name     = rtl::OUString::createFromAscii( "open" );
1226     aCommand.Handle   = -1; // n/a
1227     aCommand.Argument <<= aArg;
1228 
1229     m_xImpl->executeCommand( aCommand );
1230 
1231     return xSink->getInputStream();
1232 }
1233 
1234 //=========================================================================
1235 Reference< XStream > Content::openWriteableStream()
1236     throw( CommandAbortedException, RuntimeException, Exception )
1237 {
1238     if ( !isDocument() )
1239         return Reference< XStream >();
1240 
1241     Reference< XActiveDataStreamer > xStreamer = new ActiveDataStreamer;
1242 
1243     OpenCommandArgument2 aArg;
1244     aArg.Mode       = OpenMode::DOCUMENT;
1245     aArg.Priority   = 0; // unused
1246     aArg.Sink       = xStreamer;
1247     aArg.Properties = Sequence< Property >( 0 ); // unused
1248 
1249     Command aCommand;
1250     aCommand.Name     = rtl::OUString::createFromAscii( "open" );
1251     aCommand.Handle   = -1; // n/a
1252     aCommand.Argument <<= aArg;
1253 
1254     m_xImpl->executeCommand( aCommand );
1255 
1256     return xStreamer->getStream();
1257 }
1258 
1259 //=========================================================================
1260 Reference< XStream > Content::openWriteableStreamNoLock()
1261     throw( CommandAbortedException, RuntimeException, Exception )
1262 {
1263     if ( !isDocument() )
1264         return Reference< XStream >();
1265 
1266     Reference< XActiveDataStreamer > xStreamer = new ActiveDataStreamer;
1267 
1268     OpenCommandArgument2 aArg;
1269     aArg.Mode       = OpenMode::DOCUMENT_SHARE_DENY_NONE;
1270     aArg.Priority   = 0; // unused
1271     aArg.Sink       = xStreamer;
1272     aArg.Properties = Sequence< Property >( 0 ); // unused
1273 
1274     Command aCommand;
1275     aCommand.Name     = rtl::OUString::createFromAscii( "open" );
1276     aCommand.Handle   = -1; // n/a
1277     aCommand.Argument <<= aArg;
1278 
1279     m_xImpl->executeCommand( aCommand );
1280 
1281     return xStreamer->getStream();
1282 }
1283 
1284 //=========================================================================
1285 sal_Bool Content::openStream( const Reference< XActiveDataSink >& rSink )
1286     throw( CommandAbortedException, RuntimeException, Exception )
1287 {
1288     if ( !isDocument() )
1289         return sal_False;
1290 
1291     OpenCommandArgument2 aArg;
1292     aArg.Mode       = OpenMode::DOCUMENT;
1293     aArg.Priority   = 0; // unused
1294     aArg.Sink       = rSink;
1295     aArg.Properties = Sequence< Property >( 0 ); // unused
1296 
1297     Command aCommand;
1298     aCommand.Name     = rtl::OUString::createFromAscii( "open" );
1299     aCommand.Handle   = -1; // n/a
1300     aCommand.Argument <<= aArg;
1301 
1302     m_xImpl->executeCommand( aCommand );
1303 
1304     return sal_True;
1305 }
1306 
1307 //=========================================================================
1308 sal_Bool Content::openStream( const Reference< XOutputStream >& rStream )
1309     throw( CommandAbortedException, RuntimeException, Exception )
1310 {
1311     if ( !isDocument() )
1312         return sal_False;
1313 
1314     OpenCommandArgument2 aArg;
1315     aArg.Mode       = OpenMode::DOCUMENT;
1316     aArg.Priority   = 0; // unused
1317     aArg.Sink       = rStream;
1318     aArg.Properties = Sequence< Property >( 0 ); // unused
1319 
1320     Command aCommand;
1321     aCommand.Name     = rtl::OUString::createFromAscii( "open" );
1322     aCommand.Handle   = -1; // n/a
1323     aCommand.Argument <<= aArg;
1324 
1325     m_xImpl->executeCommand( aCommand );
1326 
1327     return sal_True;
1328 }
1329 
1330 //=========================================================================
1331 void Content::writeStream( const Reference< XInputStream >& rStream,
1332                            sal_Bool bReplaceExisting )
1333     throw( CommandAbortedException, RuntimeException, Exception )
1334 {
1335     InsertCommandArgument aArg;
1336     aArg.Data            = rStream.is() ? rStream : new EmptyInputStream;
1337     aArg.ReplaceExisting = bReplaceExisting;
1338 
1339     Command aCommand;
1340     aCommand.Name     = rtl::OUString::createFromAscii( "insert" );
1341     aCommand.Handle   = -1; // n/a
1342     aCommand.Argument <<= aArg;
1343 
1344     m_xImpl->executeCommand( aCommand );
1345 
1346     m_xImpl->inserted();
1347 }
1348 
1349 //=========================================================================
1350 Sequence< ContentInfo > Content::queryCreatableContentsInfo()
1351     throw( CommandAbortedException, RuntimeException, Exception )
1352 {
1353     // First, try it using "CreatableContentsInfo" property -> the "new" way.
1354     Sequence< ContentInfo > aInfo;
1355     if ( getPropertyValue(
1356              rtl::OUString::createFromAscii( "CreatableContentsInfo" ) )
1357          >>= aInfo )
1358         return aInfo;
1359 
1360     // Second, try it using XContentCreator interface -> the "old" way (not
1361     // providing the chance to supply an XCommandEnvironment.
1362     Reference< XContentCreator > xCreator( m_xImpl->getContent(), UNO_QUERY );
1363     if ( xCreator.is() )
1364         aInfo = xCreator->queryCreatableContentsInfo();
1365 
1366     return aInfo;
1367 }
1368 
1369 //=========================================================================
1370 sal_Bool Content::insertNewContent( const rtl::OUString& rContentType,
1371                                     const Sequence< rtl::OUString >&
1372                                         rPropertyNames,
1373                                     const Sequence< Any >& rPropertyValues,
1374                                     Content& rNewContent )
1375     throw( CommandAbortedException, RuntimeException, Exception )
1376 {
1377     return insertNewContent( rContentType,
1378                              rPropertyNames,
1379                              rPropertyValues,
1380                              new EmptyInputStream,
1381                              rNewContent );
1382 }
1383 
1384 //=========================================================================
1385 sal_Bool Content::insertNewContent( const rtl::OUString& rContentType,
1386                                     const Sequence< sal_Int32 >&
1387                                         nPropertyHandles,
1388                                     const Sequence< Any >& rPropertyValues,
1389                                     Content& rNewContent )
1390     throw( CommandAbortedException, RuntimeException, Exception )
1391 {
1392     return insertNewContent( rContentType,
1393                              nPropertyHandles,
1394                              rPropertyValues,
1395                              new EmptyInputStream,
1396                              rNewContent );
1397 }
1398 
1399 //=========================================================================
1400 sal_Bool Content::insertNewContent( const rtl::OUString& rContentType,
1401                                     const Sequence< rtl::OUString >&
1402                                         rPropertyNames,
1403                                     const Sequence< Any >& rPropertyValues,
1404                                     const Reference< XInputStream >& rData,
1405                                     Content& rNewContent )
1406     throw( CommandAbortedException, RuntimeException, Exception )
1407 {
1408     if ( rContentType.getLength() == 0 )
1409         return sal_False;
1410 
1411     // First, try it using "createNewContent" command -> the "new" way.
1412     ContentInfo aInfo;
1413     aInfo.Type = rContentType;
1414     aInfo.Attributes = 0;
1415 
1416     Command aCommand;
1417     aCommand.Name     = rtl::OUString::createFromAscii( "createNewContent" );
1418     aCommand.Handle   = -1; // n/a
1419     aCommand.Argument <<= aInfo;
1420 
1421     Reference< XContent > xNew;
1422     try
1423     {
1424         m_xImpl->executeCommand( aCommand ) >>= xNew;
1425     }
1426     catch ( RuntimeException const & )
1427     {
1428         throw;
1429     }
1430     catch ( Exception const & )
1431     {
1432     }
1433 
1434     if ( !xNew.is() )
1435     {
1436         // Second, try it using XContentCreator interface -> the "old"
1437         // way (not providing the chance to supply an XCommandEnvironment.
1438         Reference< XContentCreator > xCreator( m_xImpl->getContent(), UNO_QUERY );
1439 
1440         if ( !xCreator.is() )
1441             return sal_False;
1442 
1443         xNew = xCreator->createNewContent( aInfo );
1444 
1445         if ( !xNew.is() )
1446             return sal_False;
1447     }
1448 
1449     Content aNewContent( xNew, m_xImpl->getEnvironment() );
1450     aNewContent.setPropertyValues( rPropertyNames, rPropertyValues );
1451     aNewContent.executeCommand( rtl::OUString::createFromAscii( "insert" ),
1452                                 makeAny(
1453                                     InsertCommandArgument(
1454                                         rData.is() ? rData : new EmptyInputStream,
1455                                         sal_False /* ReplaceExisting */ ) ) );
1456     aNewContent.m_xImpl->inserted();
1457 
1458     rNewContent = aNewContent;
1459     return sal_True;
1460 }
1461 
1462 //=========================================================================
1463 sal_Bool Content::insertNewContent( const rtl::OUString& rContentType,
1464                                     const Sequence< sal_Int32 >&
1465                                         nPropertyHandles,
1466                                     const Sequence< Any >& rPropertyValues,
1467                                     const Reference< XInputStream >& rData,
1468                                     Content& rNewContent )
1469     throw( CommandAbortedException, RuntimeException, Exception )
1470 {
1471     if ( rContentType.getLength() == 0 )
1472         return sal_False;
1473 
1474     // First, try it using "createNewContent" command -> the "new" way.
1475     ContentInfo aInfo;
1476     aInfo.Type = rContentType;
1477     aInfo.Attributes = 0;
1478 
1479     Command aCommand;
1480     aCommand.Name     = rtl::OUString::createFromAscii( "createNewContent" );
1481     aCommand.Handle   = -1; // n/a
1482     aCommand.Argument <<= aInfo;
1483 
1484     Reference< XContent > xNew;
1485     try
1486     {
1487         m_xImpl->executeCommand( aCommand ) >>= xNew;
1488     }
1489     catch ( RuntimeException const & )
1490     {
1491         throw;
1492     }
1493     catch ( Exception const & )
1494     {
1495     }
1496 
1497     if ( !xNew.is() )
1498     {
1499         // Second, try it using XContentCreator interface -> the "old"
1500         // way (not providing the chance to supply an XCommandEnvironment.
1501         Reference< XContentCreator > xCreator( m_xImpl->getContent(), UNO_QUERY );
1502 
1503         if ( !xCreator.is() )
1504             return sal_False;
1505 
1506         xNew = xCreator->createNewContent( aInfo );
1507 
1508         if ( !xNew.is() )
1509             return sal_False;
1510     }
1511 
1512     Content aNewContent( xNew, m_xImpl->getEnvironment() );
1513     aNewContent.setPropertyValues( nPropertyHandles, rPropertyValues );
1514     aNewContent.executeCommand( rtl::OUString::createFromAscii( "insert" ),
1515                                 makeAny(
1516                                     InsertCommandArgument(
1517                                         rData.is() ? rData : new EmptyInputStream,
1518                                         sal_False /* ReplaceExisting */ ) ) );
1519     aNewContent.m_xImpl->inserted();
1520 
1521     rNewContent = aNewContent;
1522     return sal_True;
1523 }
1524 
1525 //=========================================================================
1526 sal_Bool Content::transferContent( const Content& rSourceContent,
1527                                    InsertOperation eOperation,
1528                                    const rtl::OUString & rTitle,
1529                                    const sal_Int32 nNameClashAction )
1530     throw( CommandAbortedException, RuntimeException, Exception )
1531 {
1532     ContentBroker* pBroker = ContentBroker::get();
1533     if ( !pBroker )
1534     {
1535         OSL_ENSURE( sal_False,
1536                     "Content::transferContent - No Content Broker!" );
1537         return sal_False;
1538     }
1539 
1540     Reference< XCommandProcessor > xCmdProc(
1541                                     pBroker->getCommandProcessorInterface() );
1542     if ( !xCmdProc.is() )
1543     {
1544         OSL_ENSURE( sal_False,
1545                     "Content::transferContent - No XCommandProcessor!" );
1546         return sal_False;
1547     }
1548 
1549     // Execute command "globalTransfer" at UCB.
1550 
1551     TransferCommandOperation eTransOp = TransferCommandOperation();
1552     switch ( eOperation )
1553     {
1554         case InsertOperation_COPY:
1555             eTransOp = TransferCommandOperation_COPY;
1556             break;
1557 
1558         case InsertOperation_MOVE:
1559             eTransOp = TransferCommandOperation_MOVE;
1560             break;
1561 
1562         case InsertOperation_LINK:
1563             eTransOp = TransferCommandOperation_LINK;
1564             break;
1565 
1566         default:
1567             ucbhelper::cancelCommandExecution(
1568                 makeAny( IllegalArgumentException(
1569                             rtl::OUString::createFromAscii(
1570                                 "Unknown transfer operation!" ),
1571                             get(),
1572                             -1 ) ),
1573                          m_xImpl->getEnvironment() );
1574             // Unreachable
1575     }
1576 
1577     GlobalTransferCommandArgument aTransferArg(
1578                                         eTransOp,
1579                                         rSourceContent.getURL(), // SourceURL
1580                                         getURL(),   // TargetFolderURL,
1581                                         rTitle,
1582                                         nNameClashAction );
1583     Command aCommand;
1584     aCommand.Name     = rtl::OUString::createFromAscii( "globalTransfer" );
1585     aCommand.Handle   = -1; // n/a
1586     aCommand.Argument <<= aTransferArg;
1587 
1588     xCmdProc->execute( aCommand, 0, m_xImpl->getEnvironment() );
1589     return sal_True;
1590 }
1591 
1592 //=========================================================================
1593 sal_Bool Content::isFolder()
1594     throw( CommandAbortedException, RuntimeException, Exception )
1595 {
1596     sal_Bool bFolder = sal_False;
1597     if ( getPropertyValue( rtl::OUString::createFromAscii( "IsFolder" ) )
1598         >>= bFolder )
1599         return bFolder;
1600 
1601      ucbhelper::cancelCommandExecution(
1602          makeAny( UnknownPropertyException(
1603                     rtl::OUString::createFromAscii(
1604                         "Unable to retreive value of property 'IsFolder'!" ),
1605                     get() ) ),
1606          m_xImpl->getEnvironment() );
1607 
1608     // Unreachable - cancelCommandExecution always throws an exception.
1609     // But some compilers complain...
1610     return sal_False;
1611 }
1612 
1613 //=========================================================================
1614 sal_Bool Content::isDocument()
1615     throw( CommandAbortedException, RuntimeException, Exception )
1616 {
1617     sal_Bool bDoc = sal_False;
1618     if ( getPropertyValue( rtl::OUString::createFromAscii( "IsDocument" ) )
1619         >>= bDoc )
1620         return bDoc;
1621 
1622      ucbhelper::cancelCommandExecution(
1623          makeAny( UnknownPropertyException(
1624                     rtl::OUString::createFromAscii(
1625                         "Unable to retreive value of property 'IsDocument'!" ),
1626                     get() ) ),
1627          m_xImpl->getEnvironment() );
1628 
1629     // Unreachable - cancelCommandExecution always throws an exception,
1630     // But some compilers complain...
1631     return sal_False;
1632 }
1633 
1634 //=========================================================================
1635 //=========================================================================
1636 //
1637 // Content_Impl Implementation.
1638 //
1639 //=========================================================================
1640 //=========================================================================
1641 
1642 Content_Impl::Content_Impl( const Reference< XMultiServiceFactory >& rSMgr,
1643                             const Reference< XContent >& rContent,
1644                             const Reference< XCommandEnvironment >& rEnv )
1645 : m_xSMgr( rSMgr ),
1646   m_xContent( rContent ),
1647   m_xEnv( rEnv ),
1648   m_nCommandId( 0 )
1649 {
1650     if ( m_xContent.is() )
1651     {
1652         m_xContentEventListener = new ContentEventListener_Impl( *this );
1653         m_xContent->addContentEventListener( m_xContentEventListener );
1654 
1655 #if OSL_DEBUG_LEVEL > 1
1656         // Only done on demand in product version for performance reasons,
1657         // but a nice debug helper.
1658         getURL();
1659 #endif
1660     }
1661 }
1662 
1663 //=========================================================================
1664 void Content_Impl::reinit( const Reference< XContent >& xContent )
1665 {
1666     osl::MutexGuard aGuard( m_aMutex );
1667 
1668     m_xCommandProcessor = 0;
1669     m_nCommandId = 0;
1670 
1671     // #92581# - Don't reset m_aURL!!!
1672 
1673     if ( m_xContent.is() )
1674     {
1675         try
1676         {
1677             m_xContent->removeContentEventListener( m_xContentEventListener );
1678         }
1679         catch ( RuntimeException const & )
1680         {
1681         }
1682     }
1683 
1684     if ( xContent.is() )
1685     {
1686         m_xContent = xContent;
1687         m_xContent->addContentEventListener( m_xContentEventListener );
1688 
1689 #if OSL_DEBUG_LEVEL > 1
1690         // Only done on demand in product version for performance reasons,
1691         // but a nice debug helper.
1692         getURL();
1693 #endif
1694     }
1695     else
1696     {
1697         // We need m_xContent's URL in order to be able to create the
1698         // content object again if demanded ( --> Content_Impl::getContent() )
1699         getURL();
1700 
1701         m_xContent = 0;
1702     }
1703 }
1704 
1705 //=========================================================================
1706 // virtual
1707 Content_Impl::~Content_Impl()
1708 {
1709     if ( m_xContent.is() )
1710     {
1711         try
1712         {
1713             m_xContent->removeContentEventListener( m_xContentEventListener );
1714         }
1715         catch ( RuntimeException const & )
1716         {
1717         }
1718     }
1719 }
1720 
1721 //=========================================================================
1722 void Content_Impl::disposing( const EventObject& Source )
1723 {
1724     Reference<XContent> xContent;
1725 
1726     {
1727         osl::MutexGuard aGuard( m_aMutex );
1728         if(Source.Source != m_xContent)
1729             return;
1730 
1731         xContent = m_xContent;
1732 
1733         m_nCommandId = 0;
1734         m_aURL = rtl::OUString();
1735         m_xCommandProcessor = 0;
1736         m_xContent = 0;
1737     }
1738 
1739     if ( xContent.is() )
1740     {
1741         try
1742         {
1743             xContent->removeContentEventListener( m_xContentEventListener );
1744         }
1745         catch ( RuntimeException const & )
1746         {
1747         }
1748     }
1749 }
1750 
1751 //=========================================================================
1752 const rtl::OUString& Content_Impl::getURL() const
1753 {
1754     if ( !m_aURL.getLength() && m_xContent.is() )
1755     {
1756         osl::MutexGuard aGuard( m_aMutex );
1757 
1758         if ( !m_aURL.getLength() && m_xContent.is() )
1759         {
1760             Reference< XContentIdentifier > xId = m_xContent->getIdentifier();
1761             if ( xId.is() )
1762                 m_aURL = xId->getContentIdentifier();
1763         }
1764     }
1765 
1766     return m_aURL;
1767 }
1768 
1769 //=========================================================================
1770 Reference< XContent > Content_Impl::getContent()
1771 {
1772     if ( !m_xContent.is() && m_aURL.getLength() )
1773     {
1774         osl::MutexGuard aGuard( m_aMutex );
1775 
1776         if ( !m_xContent.is() && m_aURL.getLength() )
1777         {
1778             ContentBroker* pBroker = ContentBroker::get();
1779 
1780             OSL_ENSURE( pBroker, "No Content Broker!" );
1781 
1782             if ( pBroker )
1783             {
1784                 OSL_ENSURE( pBroker->getContentProviderManagerInterface()
1785                                         ->queryContentProviders().getLength(),
1786                             "Content Broker not configured (no providers)!" );
1787 
1788                 Reference< XContentIdentifierFactory > xIdFac
1789                             = pBroker->getContentIdentifierFactoryInterface();
1790 
1791                 OSL_ENSURE( xIdFac.is(), "No Content Identifier factory!" );
1792 
1793                 if ( xIdFac.is() )
1794                 {
1795                     Reference< XContentIdentifier > xId
1796                                 = xIdFac->createContentIdentifier( m_aURL );
1797 
1798                     OSL_ENSURE( xId.is(), "No Content Identifier!" );
1799 
1800                     if ( xId.is() )
1801                     {
1802                         Reference< XContentProvider > xProvider
1803                             = pBroker->getContentProviderInterface();
1804 
1805                         OSL_ENSURE( xProvider.is(), "No Content Provider!" );
1806 
1807                         if ( xProvider.is() )
1808                         {
1809                             try
1810                             {
1811                                 m_xContent = xProvider->queryContent( xId );
1812                             }
1813                             catch ( IllegalIdentifierException const & )
1814                             {
1815                             }
1816 
1817                             if ( m_xContent.is() )
1818                                 m_xContent->addContentEventListener(
1819                                                 m_xContentEventListener );
1820                         }
1821                     }
1822                 }
1823             }
1824         }
1825     }
1826 
1827     return m_xContent;
1828 }
1829 
1830 //=========================================================================
1831 Reference< XCommandProcessor > Content_Impl::getCommandProcessor()
1832 {
1833     if ( !m_xCommandProcessor.is() )
1834     {
1835         osl::MutexGuard aGuard( m_aMutex );
1836 
1837         if ( !m_xCommandProcessor.is() )
1838             m_xCommandProcessor
1839                 = Reference< XCommandProcessor >( getContent(), UNO_QUERY );
1840     }
1841 
1842     return m_xCommandProcessor;
1843 }
1844 
1845 //=========================================================================
1846 sal_Int32 Content_Impl::getCommandId()
1847 {
1848     if ( m_nCommandId == 0 )
1849     {
1850         osl::MutexGuard aGuard( m_aMutex );
1851 
1852         if ( m_nCommandId == 0 )
1853         {
1854             Reference< XCommandProcessor > xProc = getCommandProcessor();
1855             if ( xProc.is() )
1856                 m_nCommandId = xProc->createCommandIdentifier();
1857         }
1858     }
1859 
1860     return m_nCommandId;
1861 }
1862 
1863 //=========================================================================
1864 Any Content_Impl::executeCommand( const Command& rCommand )
1865 {
1866     Reference< XCommandProcessor > xProc = getCommandProcessor();
1867     if ( !xProc.is() )
1868         return Any();
1869 
1870     // Execute command
1871     return xProc->execute( rCommand, getCommandId(), m_xEnv );
1872 }
1873 
1874 //=========================================================================
1875 void Content_Impl::abortCommand()
1876 {
1877     sal_Int32 nCommandId;
1878     Reference< XCommandProcessor > xCommandProcessor;
1879     {
1880         osl::MutexGuard aGuard( m_aMutex );
1881         nCommandId = m_nCommandId;
1882         xCommandProcessor = m_xCommandProcessor;
1883     }
1884 
1885     if ( ( nCommandId != 0 ) && xCommandProcessor.is() )
1886         xCommandProcessor->abort( nCommandId );
1887 }
1888 
1889 //=========================================================================
1890 inline const Reference< XCommandEnvironment >&
1891                                         Content_Impl::getEnvironment() const
1892 {
1893     return m_xEnv;
1894 }
1895 
1896 //=========================================================================
1897 inline void Content_Impl::setEnvironment(
1898                         const Reference< XCommandEnvironment >& xNewEnv )
1899 {
1900     osl::MutexGuard aGuard( m_aMutex );
1901     m_xEnv = xNewEnv;
1902 }
1903 
1904 //=========================================================================
1905 void Content_Impl::inserted()
1906 {
1907     // URL might have changed during 'insert' => recalculate in next getURL()
1908     osl::MutexGuard aGuard( m_aMutex );
1909     m_aURL = ::rtl::OUString();
1910 }
1911 
1912 //=========================================================================
1913 //=========================================================================
1914 //
1915 // ContentEventListener_Impl Implementation.
1916 //
1917 //=========================================================================
1918 //=========================================================================
1919 
1920 //=========================================================================
1921 //
1922 // XInterface methods.
1923 //
1924 //=========================================================================
1925 
1926 XINTERFACE_IMPL_2( ContentEventListener_Impl,
1927                    XContentEventListener,
1928                    XEventListener ); /* base of XContentEventListener */
1929 
1930 //=========================================================================
1931 //
1932 // XContentEventListener methods.
1933 //
1934 //=========================================================================
1935 
1936 // virtual
1937 void SAL_CALL ContentEventListener_Impl::contentEvent( const ContentEvent& evt )
1938     throw( RuntimeException )
1939 {
1940     if ( evt.Source == m_rContent.m_xContent )
1941     {
1942         switch ( evt.Action )
1943         {
1944             case ContentAction::DELETED:
1945                 m_rContent.reinit( Reference< XContent >() );
1946                 break;
1947 
1948             case ContentAction::EXCHANGED:
1949                 m_rContent.reinit( evt.Content );
1950                 break;
1951 
1952             default:
1953                 break;
1954         }
1955     }
1956 }
1957 
1958 //=========================================================================
1959 //
1960 // XEventListenr methods.
1961 //
1962 //=========================================================================
1963 
1964 // virtual
1965 void SAL_CALL ContentEventListener_Impl::disposing( const EventObject& Source )
1966     throw( RuntimeException )
1967 {
1968     m_rContent.disposing(Source);
1969 }
1970 
1971 } /* namespace ucbhelper */
1972 
1973