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