1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "sal/config.h"
24 #include <osl/diagnose.h>
25 #include <osl/mutex.hxx>
26 #include <salhelper/simplereferenceobject.hxx>
27 #include <cppuhelper/weak.hxx>
29 #include <cppuhelper/implbase1.hxx>
30 #include <com/sun/star/ucb/CheckinArgument.hpp>
31 #include <com/sun/star/ucb/ContentCreationError.hpp>
32 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
33 #include <com/sun/star/ucb/XCommandInfo.hpp>
34 #include <com/sun/star/ucb/XCommandProcessor.hpp>
35 #include <com/sun/star/ucb/Command.hpp>
36 #include <com/sun/star/ucb/CommandInfo.hpp>
37 #include <com/sun/star/ucb/ContentAction.hpp>
38 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
39 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
40 #include <com/sun/star/ucb/GlobalTransferCommandArgument2.hpp>
41 #include <com/sun/star/ucb/NameClash.hpp>
42 #include <com/sun/star/ucb/OpenMode.hpp>
43 #include <com/sun/star/ucb/XContentCreator.hpp>
44 #include <com/sun/star/ucb/XContentEventListener.hpp>
45 #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
46 #include <com/sun/star/ucb/XContentProvider.hpp>
47 #include <com/sun/star/ucb/XContentProviderManager.hpp>
48 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
49 #include <com/sun/star/ucb/SortedDynamicResultSetFactory.hpp>
50 #include <com/sun/star/ucb/UniversalContentBroker.hpp>
51 #include <com/sun/star/ucb/XUniversalContentBroker.hpp>
52 #include <com/sun/star/beans/XPropertySetInfo.hpp>
53 #include <com/sun/star/beans/Property.hpp>
54 #include <com/sun/star/beans/PropertyValue.hpp>
55 #include <com/sun/star/sdbc/XResultSet.hpp>
56 #include <com/sun/star/sdbc/XRow.hpp>
57 #include <com/sun/star/lang/IllegalArgumentException.hpp>
58 #include <com/sun/star/beans/UnknownPropertyException.hpp>
59 #include <ucbhelper/macros.hxx>
60 #include <ucbhelper/content.hxx>
61 #include <ucbhelper/activedatasink.hxx>
62 #include <ucbhelper/activedatastreamer.hxx>
63 #include <ucbhelper/interactionrequest.hxx>
64 #include <ucbhelper/cancelcommandexecution.hxx>
66 using namespace com::sun::star::container
;
67 using namespace com::sun::star::beans
;
68 using namespace com::sun::star::io
;
69 using namespace com::sun::star::lang
;
70 using namespace com::sun::star::sdbc
;
71 using namespace com::sun::star::task
;
72 using namespace com::sun::star::ucb
;
73 using namespace com::sun::star::uno
;
78 class EmptyInputStream
: public ::cppu::WeakImplHelper1
< XInputStream
>
81 virtual sal_Int32 SAL_CALL
readBytes(
82 Sequence
< sal_Int8
> & data
, sal_Int32 nBytesToRead
)
83 throw (IOException
, RuntimeException
);
84 virtual sal_Int32 SAL_CALL
readSomeBytes(
85 Sequence
< sal_Int8
> & data
, sal_Int32 nMaxBytesToRead
)
86 throw (IOException
, RuntimeException
);
87 virtual void SAL_CALL
skipBytes( sal_Int32 nBytesToSkip
)
88 throw (IOException
, RuntimeException
);
89 virtual sal_Int32 SAL_CALL
available()
90 throw (IOException
, RuntimeException
);
91 virtual void SAL_CALL
closeInput()
92 throw (IOException
, RuntimeException
);
95 sal_Int32
EmptyInputStream::readBytes(
96 Sequence
< sal_Int8
> & data
, sal_Int32
)
97 throw (IOException
, RuntimeException
)
103 sal_Int32
EmptyInputStream::readSomeBytes(
104 Sequence
< sal_Int8
> & data
, sal_Int32
)
105 throw (IOException
, RuntimeException
)
111 void EmptyInputStream::skipBytes( sal_Int32
)
112 throw (IOException
, RuntimeException
)
116 sal_Int32
EmptyInputStream::available()
117 throw (IOException
, RuntimeException
)
122 void EmptyInputStream::closeInput()
123 throw (IOException
, RuntimeException
)
128 //=========================================================================
129 //=========================================================================
131 // class ContentEventListener_Impl.
133 //=========================================================================
134 //=========================================================================
136 class ContentEventListener_Impl
: public cppu::OWeakObject
,
137 public XContentEventListener
139 Content_Impl
& m_rContent
;
142 ContentEventListener_Impl( Content_Impl
& rContent
)
143 : m_rContent( rContent
) {}
148 // XContentEventListener
149 virtual void SAL_CALL
contentEvent( const ContentEvent
& evt
)
150 throw( RuntimeException
);
152 // XEventListener ( base of XContentEventListener )
153 virtual void SAL_CALL
disposing( const EventObject
& Source
)
154 throw( RuntimeException
);
157 //=========================================================================
158 //=========================================================================
160 // class Content_Impl.
162 //=========================================================================
163 //=========================================================================
165 class Content_Impl
: public salhelper::SimpleReferenceObject
167 friend class ContentEventListener_Impl
;
169 mutable rtl::OUString m_aURL
;
170 Reference
< XComponentContext
> m_xCtx
;
171 Reference
< XContent
> m_xContent
;
172 Reference
< XCommandProcessor
> m_xCommandProcessor
;
173 Reference
< XCommandEnvironment
> m_xEnv
;
174 Reference
< XContentEventListener
> m_xContentEventListener
;
175 mutable osl::Mutex m_aMutex
;
176 sal_Int32 m_nCommandId
;
179 void reinit( const Reference
< XContent
>& xContent
);
180 void disposing(const EventObject
& Source
);
183 Content_Impl() : m_nCommandId( 0 ) {};
184 Content_Impl( const Reference
< XComponentContext
>& rCtx
,
185 const Reference
< XContent
>& rContent
,
186 const Reference
< XCommandEnvironment
>& rEnv
);
188 virtual ~Content_Impl();
190 const rtl::OUString
& getURL() const;
191 Reference
< XContent
> getContent();
192 Reference
< XCommandProcessor
> getCommandProcessor();
193 sal_Int32
getCommandId();
194 Reference
< XComponentContext
> getComponentContext()
195 { assert(m_xCtx
.is()); return m_xCtx
; }
197 Any
executeCommand( const Command
& rCommand
);
199 inline const Reference
< XCommandEnvironment
>& getEnvironment() const;
200 inline void setEnvironment(
201 const Reference
< XCommandEnvironment
>& xNewEnv
);
206 //=========================================================================
208 //=========================================================================
210 static void ensureContentProviderForURL( const Reference
< XUniversalContentBroker
>& rBroker
,
211 const rtl::OUString
& rURL
)
212 throw ( ContentCreationException
, RuntimeException
)
214 Reference
< XContentProvider
> xProv
215 = rBroker
->queryContentProvider( rURL
);
218 throw ContentCreationException(
219 "No Content Provider available for URL: " + rURL
,
220 Reference
< XInterface
>(),
221 ContentCreationError_NO_CONTENT_PROVIDER
);
225 //=========================================================================
226 static Reference
< XContentIdentifier
> getContentIdentifier(
227 const Reference
< XUniversalContentBroker
> & rBroker
,
228 const rtl::OUString
& rURL
,
230 throw ( ContentCreationException
, RuntimeException
)
232 Reference
< XContentIdentifier
> xId
233 = rBroker
->createContentIdentifier( rURL
);
240 ensureContentProviderForURL( rBroker
, rURL
);
242 throw ContentCreationException(
243 "Unable to create Content Identifier!",
244 Reference
< XInterface
>(),
245 ContentCreationError_IDENTIFIER_CREATION_FAILED
);
248 return Reference
< XContentIdentifier
>();
251 //=========================================================================
252 static Reference
< XContent
> getContent(
253 const Reference
< XUniversalContentBroker
> & rBroker
,
254 const Reference
< XContentIdentifier
> & xId
,
256 throw ( ContentCreationException
, RuntimeException
)
258 Reference
< XContent
> xContent
;
262 xContent
= rBroker
->queryContent( xId
);
264 catch ( IllegalIdentifierException
const & e
)
275 ensureContentProviderForURL( rBroker
, xId
->getContentIdentifier() );
277 throw ContentCreationException(
278 "Unable to create Content! " + msg
,
279 Reference
< XInterface
>(),
280 ContentCreationError_CONTENT_CREATION_FAILED
);
283 return Reference
< XContent
>();
286 //=========================================================================
287 //=========================================================================
289 // Content Implementation.
291 //=========================================================================
292 //=========================================================================
295 : m_xImpl( new Content_Impl
)
299 //=========================================================================
300 Content::Content( const rtl::OUString
& rURL
,
301 const Reference
< XCommandEnvironment
>& rEnv
,
302 const Reference
< XComponentContext
>& rCtx
)
303 throw ( ContentCreationException
, RuntimeException
)
305 Reference
< XUniversalContentBroker
> pBroker(
306 UniversalContentBroker::create( rCtx
) );
308 Reference
< XContentIdentifier
> xId
309 = getContentIdentifier( pBroker
, rURL
, true );
311 Reference
< XContent
> xContent
= getContent( pBroker
, xId
, true );
313 m_xImpl
= new Content_Impl( rCtx
, xContent
, rEnv
);
316 //=========================================================================
317 Content::Content( const Reference
< XContent
>& rContent
,
318 const Reference
< XCommandEnvironment
>& rEnv
,
319 const Reference
< XComponentContext
>& rCtx
)
320 throw ( ContentCreationException
, RuntimeException
)
322 m_xImpl
= new Content_Impl( rCtx
, rContent
, rEnv
);
325 //=========================================================================
326 Content::Content( const Content
& rOther
)
328 m_xImpl
= rOther
.m_xImpl
;
331 //=========================================================================
333 sal_Bool
Content::create( const rtl::OUString
& rURL
,
334 const Reference
< XCommandEnvironment
>& rEnv
,
335 const Reference
< XComponentContext
>& rCtx
,
338 Reference
< XUniversalContentBroker
> pBroker(
339 UniversalContentBroker::create( rCtx
) );
341 Reference
< XContentIdentifier
> xId
342 = getContentIdentifier( pBroker
, rURL
, false );
346 Reference
< XContent
> xContent
= getContent( pBroker
, xId
, false );
347 if ( !xContent
.is() )
351 = new Content_Impl( rCtx
, xContent
, rEnv
);
356 //=========================================================================
361 //=========================================================================
362 Content
& Content::operator=( const Content
& rOther
)
364 m_xImpl
= rOther
.m_xImpl
;
368 //=========================================================================
369 Reference
< XContent
> Content::get() const
371 return m_xImpl
->getContent();
374 //=========================================================================
375 const rtl::OUString
& Content::getURL() const
377 return m_xImpl
->getURL();
380 //=========================================================================
381 const Reference
< XCommandEnvironment
>& Content::getCommandEnvironment() const
383 return m_xImpl
->getEnvironment();
386 //=========================================================================
387 void Content::setCommandEnvironment(
388 const Reference
< XCommandEnvironment
>& xNewEnv
)
390 m_xImpl
->setEnvironment( xNewEnv
);
393 //=========================================================================
394 Reference
< XCommandInfo
> Content::getCommands()
395 throw( CommandAbortedException
, RuntimeException
, Exception
)
398 aCommand
.Name
= rtl::OUString("getCommandInfo");
399 aCommand
.Handle
= -1; // n/a
400 aCommand
.Argument
= Any();
402 Any aResult
= m_xImpl
->executeCommand( aCommand
);
404 Reference
< XCommandInfo
> xInfo
;
409 //=========================================================================
410 Reference
< XPropertySetInfo
> Content::getProperties()
411 throw( CommandAbortedException
, RuntimeException
, Exception
)
414 aCommand
.Name
= rtl::OUString("getPropertySetInfo");
415 aCommand
.Handle
= -1; // n/a
416 aCommand
.Argument
= Any();
418 Any aResult
= m_xImpl
->executeCommand( aCommand
);
420 Reference
< XPropertySetInfo
> xInfo
;
425 //=========================================================================
426 Any
Content::getPropertyValue( const rtl::OUString
& rPropertyName
)
427 throw( CommandAbortedException
, RuntimeException
, Exception
)
429 Sequence
< rtl::OUString
> aNames( 1 );
430 aNames
.getArray()[ 0 ] = rPropertyName
;
432 Sequence
< Any
> aRet
= getPropertyValues( aNames
);
433 return aRet
.getConstArray()[ 0 ];
436 //=========================================================================
437 Any
Content::setPropertyValue( const rtl::OUString
& rName
,
439 throw( CommandAbortedException
, RuntimeException
, Exception
)
441 Sequence
< rtl::OUString
> aNames( 1 );
442 aNames
.getArray()[ 0 ] = rName
;
444 Sequence
< Any
> aValues( 1 );
445 aValues
.getArray()[ 0 ] = rValue
;
447 Sequence
< Any
> aErrors
= setPropertyValues( aNames
, aValues
);
448 return aErrors
.getConstArray()[ 0 ];
451 //=========================================================================
452 Sequence
< Any
> Content::getPropertyValues(
453 const Sequence
< rtl::OUString
>& rPropertyNames
)
454 throw( CommandAbortedException
, RuntimeException
, Exception
)
456 Reference
< XRow
> xRow
= getPropertyValuesInterface( rPropertyNames
);
458 sal_Int32 nCount
= rPropertyNames
.getLength();
459 Sequence
< Any
> aValues( nCount
);
463 Any
* pValues
= aValues
.getArray();
465 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
466 pValues
[ n
] = xRow
->getObject( n
+ 1, Reference
< XNameAccess
>() );
472 //=========================================================================
473 Reference
< XRow
> Content::getPropertyValuesInterface(
474 const Sequence
< rtl::OUString
>& rPropertyNames
)
475 throw( CommandAbortedException
, RuntimeException
, Exception
)
477 sal_Int32 nCount
= rPropertyNames
.getLength();
478 Sequence
< Property
> aProps( nCount
);
479 Property
* pProps
= aProps
.getArray();
481 const rtl::OUString
* pNames
= rPropertyNames
.getConstArray();
483 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
485 Property
& rProp
= pProps
[ n
];
487 rProp
.Name
= pNames
[ n
];
488 rProp
.Handle
= -1; // n/a
490 // rProp.Attributes = ;
494 aCommand
.Name
= rtl::OUString("getPropertyValues");
495 aCommand
.Handle
= -1; // n/a
496 aCommand
.Argument
<<= aProps
;
498 Any aResult
= m_xImpl
->executeCommand( aCommand
);
500 Reference
< XRow
> xRow
;
505 //=========================================================================
506 Sequence
< Any
> Content::setPropertyValues(
507 const Sequence
< rtl::OUString
>& rPropertyNames
,
508 const Sequence
< Any
>& rValues
)
509 throw( CommandAbortedException
, RuntimeException
, Exception
)
511 if ( rPropertyNames
.getLength() != rValues
.getLength() )
513 ucbhelper::cancelCommandExecution(
514 makeAny( IllegalArgumentException(
516 "Length of property names sequence and value "
517 "sequence are unequal!" ),
520 m_xImpl
->getEnvironment() );
524 sal_Int32 nCount
= rValues
.getLength();
525 Sequence
< PropertyValue
> aProps( nCount
);
526 PropertyValue
* pProps
= aProps
.getArray();
528 const rtl::OUString
* pNames
= rPropertyNames
.getConstArray();
529 const Any
* pValues
= rValues
.getConstArray();
531 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
533 PropertyValue
& rProp
= pProps
[ n
];
535 rProp
.Name
= pNames
[ n
];
536 rProp
.Handle
= -1; // n/a
537 rProp
.Value
= pValues
[ n
];
542 aCommand
.Name
= rtl::OUString("setPropertyValues");
543 aCommand
.Handle
= -1; // n/a
544 aCommand
.Argument
<<= aProps
;
546 Any aResult
= m_xImpl
->executeCommand( aCommand
);
548 Sequence
< Any
> aErrors
;
553 //=========================================================================
554 Any
Content::executeCommand( const rtl::OUString
& rCommandName
,
555 const Any
& rCommandArgument
)
556 throw( CommandAbortedException
, RuntimeException
, Exception
)
559 aCommand
.Name
= rCommandName
;
560 aCommand
.Handle
= -1; // n/a
561 aCommand
.Argument
= rCommandArgument
;
563 return m_xImpl
->executeCommand( aCommand
);
566 //=========================================================================
567 Any
Content::createCursorAny( const Sequence
< rtl::OUString
>& rPropertyNames
,
568 ResultSetInclude eMode
)
569 throw( CommandAbortedException
, RuntimeException
, Exception
)
571 sal_Int32 nCount
= rPropertyNames
.getLength();
572 Sequence
< Property
> aProps( nCount
);
573 Property
* pProps
= aProps
.getArray();
574 const rtl::OUString
* pNames
= rPropertyNames
.getConstArray();
575 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
577 Property
& rProp
= pProps
[ n
];
578 rProp
.Name
= pNames
[ n
];
579 rProp
.Handle
= -1; // n/a
582 OpenCommandArgument2 aArg
;
583 aArg
.Mode
= ( eMode
== INCLUDE_FOLDERS_ONLY
)
585 : ( eMode
== INCLUDE_DOCUMENTS_ONLY
)
586 ? OpenMode::DOCUMENTS
: OpenMode::ALL
;
587 aArg
.Priority
= 0; // unused
588 aArg
.Sink
= Reference
< XInterface
>(); // unused
589 aArg
.Properties
= aProps
;
592 aCommand
.Name
= rtl::OUString("open");
593 aCommand
.Handle
= -1; // n/a
594 aCommand
.Argument
<<= aArg
;
596 return m_xImpl
->executeCommand( aCommand
);
599 //=========================================================================
600 Reference
< XResultSet
> Content::createCursor(
601 const Sequence
< rtl::OUString
>& rPropertyNames
,
602 ResultSetInclude eMode
)
603 throw( CommandAbortedException
, RuntimeException
, Exception
)
605 Any aCursorAny
= createCursorAny( rPropertyNames
, eMode
);
607 Reference
< XDynamicResultSet
> xDynSet
;
608 Reference
< XResultSet
> aResult
;
610 aCursorAny
>>= xDynSet
;
612 aResult
= xDynSet
->getStaticResultSet();
614 OSL_ENSURE( aResult
.is(), "Content::createCursor - no cursor!" );
618 // Former, the open command directly returned a XResultSet.
619 aCursorAny
>>= aResult
;
621 OSL_ENSURE( !aResult
.is(),
622 "Content::createCursor - open-Command must "
623 "return a Reference< XDynnamicResultSet >!" );
629 //=========================================================================
630 Reference
< XDynamicResultSet
> Content::createDynamicCursor(
631 const Sequence
< rtl::OUString
>& rPropertyNames
,
632 ResultSetInclude eMode
)
633 throw( CommandAbortedException
, RuntimeException
, Exception
)
635 Reference
< XDynamicResultSet
> aResult
;
636 createCursorAny( rPropertyNames
, eMode
) >>= aResult
;
638 OSL_ENSURE( aResult
.is(), "Content::createDynamicCursor - no cursor!" );
643 //=========================================================================
644 Reference
< XResultSet
> Content::createSortedCursor(
645 const Sequence
< rtl::OUString
>& rPropertyNames
,
646 const Sequence
< NumberedSortingInfo
>& rSortInfo
,
647 Reference
< XAnyCompareFactory
> rAnyCompareFactory
,
648 ResultSetInclude eMode
)
649 throw( CommandAbortedException
, RuntimeException
, Exception
)
651 Reference
< XResultSet
> aResult
;
652 Reference
< XDynamicResultSet
> aDynSet
;
654 Any aCursorAny
= createCursorAny( rPropertyNames
, eMode
);
656 aCursorAny
>>= aDynSet
;
660 Reference
< XDynamicResultSet
> aDynResult
;
662 if( m_xImpl
->getComponentContext().is() )
664 Reference
< XSortedDynamicResultSetFactory
> aSortFactory
=
665 SortedDynamicResultSetFactory::create( m_xImpl
->getComponentContext());
667 aDynResult
= aSortFactory
->createSortedDynamicResultSet( aDynSet
,
669 rAnyCompareFactory
);
672 OSL_ENSURE( aDynResult
.is(), "Content::createSortedCursor - no sorted cursor!\n" );
674 if( aDynResult
.is() )
675 aResult
= aDynResult
->getStaticResultSet();
677 aResult
= aDynSet
->getStaticResultSet();
680 OSL_ENSURE( aResult
.is(), "Content::createSortedCursor - no cursor!" );
684 // Former, the open command directly returned a XResultSet.
685 aCursorAny
>>= aResult
;
687 OSL_ENSURE( !aResult
.is(),
688 "Content::createCursor - open-Command must "
689 "return a Reference< XDynnamicResultSet >!" );
695 //=========================================================================
696 Reference
< XInputStream
> Content::openStream()
697 throw( CommandAbortedException
, RuntimeException
, Exception
)
700 return Reference
< XInputStream
>();
702 Reference
< XActiveDataSink
> xSink
= new ActiveDataSink
;
704 OpenCommandArgument2 aArg
;
705 aArg
.Mode
= OpenMode::DOCUMENT
;
706 aArg
.Priority
= 0; // unused
708 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
711 aCommand
.Name
= rtl::OUString("open");
712 aCommand
.Handle
= -1; // n/a
713 aCommand
.Argument
<<= aArg
;
715 m_xImpl
->executeCommand( aCommand
);
717 return xSink
->getInputStream();
720 //=========================================================================
721 Reference
< XInputStream
> Content::openStreamNoLock()
722 throw( CommandAbortedException
, RuntimeException
, Exception
)
725 return Reference
< XInputStream
>();
727 Reference
< XActiveDataSink
> xSink
= new ActiveDataSink
;
729 OpenCommandArgument2 aArg
;
730 aArg
.Mode
= OpenMode::DOCUMENT_SHARE_DENY_NONE
;
731 aArg
.Priority
= 0; // unused
733 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
736 aCommand
.Name
= rtl::OUString("open");
737 aCommand
.Handle
= -1; // n/a
738 aCommand
.Argument
<<= aArg
;
740 m_xImpl
->executeCommand( aCommand
);
742 return xSink
->getInputStream();
745 //=========================================================================
746 Reference
< XStream
> Content::openWriteableStream()
747 throw( CommandAbortedException
, RuntimeException
, Exception
)
750 return Reference
< XStream
>();
752 Reference
< XActiveDataStreamer
> xStreamer
= new ActiveDataStreamer
;
754 OpenCommandArgument2 aArg
;
755 aArg
.Mode
= OpenMode::DOCUMENT
;
756 aArg
.Priority
= 0; // unused
757 aArg
.Sink
= xStreamer
;
758 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
761 aCommand
.Name
= rtl::OUString("open");
762 aCommand
.Handle
= -1; // n/a
763 aCommand
.Argument
<<= aArg
;
765 m_xImpl
->executeCommand( aCommand
);
767 return xStreamer
->getStream();
770 //=========================================================================
771 Reference
< XStream
> Content::openWriteableStreamNoLock()
772 throw( CommandAbortedException
, RuntimeException
, Exception
)
775 return Reference
< XStream
>();
777 Reference
< XActiveDataStreamer
> xStreamer
= new ActiveDataStreamer
;
779 OpenCommandArgument2 aArg
;
780 aArg
.Mode
= OpenMode::DOCUMENT_SHARE_DENY_NONE
;
781 aArg
.Priority
= 0; // unused
782 aArg
.Sink
= xStreamer
;
783 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
786 aCommand
.Name
= rtl::OUString("open");
787 aCommand
.Handle
= -1; // n/a
788 aCommand
.Argument
<<= aArg
;
790 m_xImpl
->executeCommand( aCommand
);
792 return xStreamer
->getStream();
795 //=========================================================================
796 sal_Bool
Content::openStream( const Reference
< XActiveDataSink
>& rSink
)
797 throw( CommandAbortedException
, RuntimeException
, Exception
)
802 OpenCommandArgument2 aArg
;
803 aArg
.Mode
= OpenMode::DOCUMENT
;
804 aArg
.Priority
= 0; // unused
806 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
809 aCommand
.Name
= rtl::OUString("open");
810 aCommand
.Handle
= -1; // n/a
811 aCommand
.Argument
<<= aArg
;
813 m_xImpl
->executeCommand( aCommand
);
818 //=========================================================================
819 sal_Bool
Content::openStream( const Reference
< XOutputStream
>& rStream
)
820 throw( CommandAbortedException
, RuntimeException
, Exception
)
825 OpenCommandArgument2 aArg
;
826 aArg
.Mode
= OpenMode::DOCUMENT
;
827 aArg
.Priority
= 0; // unused
829 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
832 aCommand
.Name
= rtl::OUString("open");
833 aCommand
.Handle
= -1; // n/a
834 aCommand
.Argument
<<= aArg
;
836 m_xImpl
->executeCommand( aCommand
);
841 //=========================================================================
842 void Content::writeStream( const Reference
< XInputStream
>& rStream
,
843 sal_Bool bReplaceExisting
)
844 throw( CommandAbortedException
, RuntimeException
, Exception
)
846 InsertCommandArgument aArg
;
847 aArg
.Data
= rStream
.is() ? rStream
: new EmptyInputStream
;
848 aArg
.ReplaceExisting
= bReplaceExisting
;
851 aCommand
.Name
= rtl::OUString("insert");
852 aCommand
.Handle
= -1; // n/a
853 aCommand
.Argument
<<= aArg
;
855 m_xImpl
->executeCommand( aCommand
);
860 //=========================================================================
861 Sequence
< ContentInfo
> Content::queryCreatableContentsInfo()
862 throw( CommandAbortedException
, RuntimeException
, Exception
)
864 // First, try it using "CreatableContentsInfo" property -> the "new" way.
865 Sequence
< ContentInfo
> aInfo
;
866 if ( getPropertyValue(
867 rtl::OUString("CreatableContentsInfo") )
871 // Second, try it using XContentCreator interface -> the "old" way (not
872 // providing the chance to supply an XCommandEnvironment.
873 Reference
< XContentCreator
> xCreator( m_xImpl
->getContent(), UNO_QUERY
);
875 aInfo
= xCreator
->queryCreatableContentsInfo();
880 //=========================================================================
881 sal_Bool
Content::insertNewContent( const rtl::OUString
& rContentType
,
882 const Sequence
< rtl::OUString
>&
884 const Sequence
< Any
>& rPropertyValues
,
885 Content
& rNewContent
)
886 throw( CommandAbortedException
, RuntimeException
, Exception
)
888 return insertNewContent( rContentType
,
891 new EmptyInputStream
,
895 //=========================================================================
896 sal_Bool
Content::insertNewContent( const rtl::OUString
& rContentType
,
897 const Sequence
< rtl::OUString
>&
899 const Sequence
< Any
>& rPropertyValues
,
900 const Reference
< XInputStream
>& rData
,
901 Content
& rNewContent
)
902 throw( CommandAbortedException
, RuntimeException
, Exception
)
904 if ( rContentType
.isEmpty() )
907 // First, try it using "createNewContent" command -> the "new" way.
909 aInfo
.Type
= rContentType
;
910 aInfo
.Attributes
= 0;
913 aCommand
.Name
= rtl::OUString("createNewContent");
914 aCommand
.Handle
= -1; // n/a
915 aCommand
.Argument
<<= aInfo
;
917 Reference
< XContent
> xNew
;
920 m_xImpl
->executeCommand( aCommand
) >>= xNew
;
922 catch ( RuntimeException
const & )
926 catch ( Exception
const & )
932 // Second, try it using XContentCreator interface -> the "old"
933 // way (not providing the chance to supply an XCommandEnvironment.
934 Reference
< XContentCreator
> xCreator( m_xImpl
->getContent(), UNO_QUERY
);
936 if ( !xCreator
.is() )
939 xNew
= xCreator
->createNewContent( aInfo
);
946 xNew
, m_xImpl
->getEnvironment(), m_xImpl
->getComponentContext() );
947 aNewContent
.setPropertyValues( rPropertyNames
, rPropertyValues
);
948 aNewContent
.executeCommand( rtl::OUString("insert"),
950 InsertCommandArgument(
951 rData
.is() ? rData
: new EmptyInputStream
,
952 sal_False
/* ReplaceExisting */ ) ) );
953 aNewContent
.m_xImpl
->inserted();
955 rNewContent
= aNewContent
;
959 //=========================================================================
960 sal_Bool
Content::transferContent( const Content
& rSourceContent
,
961 InsertOperation eOperation
,
962 const rtl::OUString
& rTitle
,
963 const sal_Int32 nNameClashAction
,
964 const rtl::OUString
& rMimeType
,
966 const rtl::OUString
& rVersionComment
,
967 rtl::OUString
* pResultURL
)
968 throw( CommandAbortedException
, RuntimeException
, Exception
)
970 Reference
< XUniversalContentBroker
> pBroker(
971 UniversalContentBroker::create( m_xImpl
->getComponentContext() ) );
973 // Execute command "globalTransfer" at UCB.
975 TransferCommandOperation eTransOp
= TransferCommandOperation();
976 rtl::OUString
sCommand( "globalTransfer" );
977 bool bCheckIn
= false;
978 switch ( eOperation
)
980 case InsertOperation_COPY
:
981 eTransOp
= TransferCommandOperation_COPY
;
984 case InsertOperation_MOVE
:
985 eTransOp
= TransferCommandOperation_MOVE
;
988 case InsertOperation_LINK
:
989 eTransOp
= TransferCommandOperation_LINK
;
992 case InsertOperation_CHECKIN
:
993 eTransOp
= TransferCommandOperation_COPY
;
994 sCommand
= rtl::OUString( "checkin" );
999 ucbhelper::cancelCommandExecution(
1000 makeAny( IllegalArgumentException(
1002 "Unknown transfer operation!" ),
1005 m_xImpl
->getEnvironment() );
1009 aCommand
.Name
= sCommand
;
1010 aCommand
.Handle
= -1; // n/a
1014 GlobalTransferCommandArgument2
aTransferArg(
1016 rSourceContent
.getURL(), // SourceURL
1017 getURL(), // TargetFolderURL,
1021 aCommand
.Argument
<<= aTransferArg
;
1025 CheckinArgument
aCheckinArg( bMajorVersion
, rVersionComment
,
1026 rSourceContent
.getURL(), getURL(), rTitle
, rMimeType
);
1027 aCommand
.Argument
<<= aCheckinArg
;
1030 Any aRet
= pBroker
->execute( aCommand
, 0, m_xImpl
->getEnvironment() );
1031 if ( pResultURL
!= NULL
)
1032 aRet
>>= *pResultURL
;
1036 //=========================================================================
1037 sal_Bool
Content::isFolder()
1038 throw( CommandAbortedException
, RuntimeException
, Exception
)
1040 sal_Bool bFolder
= sal_False
;
1041 if ( getPropertyValue( rtl::OUString("IsFolder") )
1045 ucbhelper::cancelCommandExecution(
1046 makeAny( UnknownPropertyException(
1048 "Unable to retreive value of property 'IsFolder'!" ),
1050 m_xImpl
->getEnvironment() );
1052 // Unreachable - cancelCommandExecution always throws an exception.
1053 // But some compilers complain...
1057 //=========================================================================
1058 sal_Bool
Content::isDocument()
1059 throw( CommandAbortedException
, RuntimeException
, Exception
)
1061 sal_Bool bDoc
= sal_False
;
1062 if ( getPropertyValue( rtl::OUString("IsDocument") )
1066 ucbhelper::cancelCommandExecution(
1067 makeAny( UnknownPropertyException(
1069 "Unable to retreive value of property 'IsDocument'!" ),
1071 m_xImpl
->getEnvironment() );
1073 // Unreachable - cancelCommandExecution always throws an exception,
1074 // But some compilers complain...
1078 //=========================================================================
1079 //=========================================================================
1081 // Content_Impl Implementation.
1083 //=========================================================================
1084 //=========================================================================
1086 Content_Impl::Content_Impl( const Reference
< XComponentContext
>& rCtx
,
1087 const Reference
< XContent
>& rContent
,
1088 const Reference
< XCommandEnvironment
>& rEnv
)
1090 m_xContent( rContent
),
1095 if ( m_xContent
.is() )
1097 m_xContentEventListener
= new ContentEventListener_Impl( *this );
1098 m_xContent
->addContentEventListener( m_xContentEventListener
);
1100 #if OSL_DEBUG_LEVEL > 1
1101 // Only done on demand in product version for performance reasons,
1102 // but a nice debug helper.
1108 //=========================================================================
1109 void Content_Impl::reinit( const Reference
< XContent
>& xContent
)
1111 osl::MutexGuard
aGuard( m_aMutex
);
1113 m_xCommandProcessor
= 0;
1116 // #92581# - Don't reset m_aURL!!!
1118 if ( m_xContent
.is() )
1122 m_xContent
->removeContentEventListener( m_xContentEventListener
);
1124 catch ( RuntimeException
const & )
1129 if ( xContent
.is() )
1131 m_xContent
= xContent
;
1132 m_xContent
->addContentEventListener( m_xContentEventListener
);
1134 #if OSL_DEBUG_LEVEL > 1
1135 // Only done on demand in product version for performance reasons,
1136 // but a nice debug helper.
1142 // We need m_xContent's URL in order to be able to create the
1143 // content object again if demanded ( --> Content_Impl::getContent() )
1150 //=========================================================================
1152 Content_Impl::~Content_Impl()
1154 if ( m_xContent
.is() )
1158 m_xContent
->removeContentEventListener( m_xContentEventListener
);
1160 catch ( RuntimeException
const & )
1166 //=========================================================================
1167 void Content_Impl::disposing( const EventObject
& Source
)
1169 Reference
<XContent
> xContent
;
1172 osl::MutexGuard
aGuard( m_aMutex
);
1173 if(Source
.Source
!= m_xContent
)
1176 xContent
= m_xContent
;
1179 m_aURL
= rtl::OUString();
1180 m_xCommandProcessor
= 0;
1184 if ( xContent
.is() )
1188 xContent
->removeContentEventListener( m_xContentEventListener
);
1190 catch ( RuntimeException
const & )
1196 //=========================================================================
1197 const rtl::OUString
& Content_Impl::getURL() const
1199 if ( m_aURL
.isEmpty() && m_xContent
.is() )
1201 osl::MutexGuard
aGuard( m_aMutex
);
1203 if ( m_aURL
.isEmpty() && m_xContent
.is() )
1205 Reference
< XContentIdentifier
> xId
= m_xContent
->getIdentifier();
1207 m_aURL
= xId
->getContentIdentifier();
1214 //=========================================================================
1215 Reference
< XContent
> Content_Impl::getContent()
1217 if ( !m_xContent
.is() && !m_aURL
.isEmpty() )
1219 osl::MutexGuard
aGuard( m_aMutex
);
1221 if ( !m_xContent
.is() && !m_aURL
.isEmpty() )
1223 Reference
< XUniversalContentBroker
> pBroker(
1224 UniversalContentBroker::create( getComponentContext() ) );
1226 OSL_ENSURE( pBroker
->queryContentProviders().getLength(),
1227 "Content Broker not configured (no providers)!" );
1229 Reference
< XContentIdentifier
> xId
1230 = pBroker
->createContentIdentifier( m_aURL
);
1232 OSL_ENSURE( xId
.is(), "No Content Identifier!" );
1238 m_xContent
= pBroker
->queryContent( xId
);
1240 catch ( IllegalIdentifierException
const & )
1244 if ( m_xContent
.is() )
1245 m_xContent
->addContentEventListener(
1246 m_xContentEventListener
);
1254 //=========================================================================
1255 Reference
< XCommandProcessor
> Content_Impl::getCommandProcessor()
1257 if ( !m_xCommandProcessor
.is() )
1259 osl::MutexGuard
aGuard( m_aMutex
);
1261 if ( !m_xCommandProcessor
.is() )
1263 = Reference
< XCommandProcessor
>( getContent(), UNO_QUERY
);
1266 return m_xCommandProcessor
;
1269 //=========================================================================
1270 sal_Int32
Content_Impl::getCommandId()
1272 if ( m_nCommandId
== 0 )
1274 osl::MutexGuard
aGuard( m_aMutex
);
1276 if ( m_nCommandId
== 0 )
1278 Reference
< XCommandProcessor
> xProc
= getCommandProcessor();
1280 m_nCommandId
= xProc
->createCommandIdentifier();
1284 return m_nCommandId
;
1287 //=========================================================================
1288 Any
Content_Impl::executeCommand( const Command
& rCommand
)
1290 Reference
< XCommandProcessor
> xProc
= getCommandProcessor();
1295 return xProc
->execute( rCommand
, getCommandId(), m_xEnv
);
1298 //=========================================================================
1299 inline const Reference
< XCommandEnvironment
>&
1300 Content_Impl::getEnvironment() const
1305 //=========================================================================
1306 inline void Content_Impl::setEnvironment(
1307 const Reference
< XCommandEnvironment
>& xNewEnv
)
1309 osl::MutexGuard
aGuard( m_aMutex
);
1313 //=========================================================================
1314 void Content_Impl::inserted()
1316 // URL might have changed during 'insert' => recalculate in next getURL()
1317 osl::MutexGuard
aGuard( m_aMutex
);
1318 m_aURL
= ::rtl::OUString();
1321 //=========================================================================
1322 //=========================================================================
1324 // ContentEventListener_Impl Implementation.
1326 //=========================================================================
1327 //=========================================================================
1329 //=========================================================================
1331 // XInterface methods.
1333 //=========================================================================
1335 XINTERFACE_IMPL_2( ContentEventListener_Impl
,
1336 XContentEventListener
,
1337 XEventListener
); /* base of XContentEventListener */
1339 //=========================================================================
1341 // XContentEventListener methods.
1343 //=========================================================================
1346 void SAL_CALL
ContentEventListener_Impl::contentEvent( const ContentEvent
& evt
)
1347 throw( RuntimeException
)
1349 if ( evt
.Source
== m_rContent
.m_xContent
)
1351 switch ( evt
.Action
)
1353 case ContentAction::DELETED
:
1354 m_rContent
.reinit( Reference
< XContent
>() );
1357 case ContentAction::EXCHANGED
:
1358 m_rContent
.reinit( evt
.Content
);
1367 //=========================================================================
1369 // XEventListenr methods.
1371 //=========================================================================
1374 void SAL_CALL
ContentEventListener_Impl::disposing( const EventObject
& Source
)
1375 throw( RuntimeException
)
1377 m_rContent
.disposing(Source
);
1380 } /* namespace ucbhelper */
1382 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */