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