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 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
;
178 void reinit( const Reference
< XContent
>& xContent
);
179 void disposing(const EventObject
& Source
);
183 Content_Impl( const Reference
< XComponentContext
>& rCtx
,
184 const Reference
< XContent
>& rContent
,
185 const Reference
< XCommandEnvironment
>& rEnv
);
187 virtual ~Content_Impl();
189 const OUString
& getURL() const;
190 Reference
< XContent
> getContent();
191 Reference
< XCommandProcessor
> getCommandProcessor();
192 Reference
< XComponentContext
> getComponentContext()
193 { assert(m_xCtx
.is()); return m_xCtx
; }
195 Any
executeCommand( const Command
& rCommand
);
197 inline const Reference
< XCommandEnvironment
>& getEnvironment() const;
198 inline void setEnvironment(
199 const Reference
< XCommandEnvironment
>& xNewEnv
);
204 //=========================================================================
206 //=========================================================================
208 static void ensureContentProviderForURL( const Reference
< XUniversalContentBroker
>& rBroker
,
209 const OUString
& rURL
)
210 throw ( ContentCreationException
, RuntimeException
)
212 Reference
< XContentProvider
> xProv
213 = rBroker
->queryContentProvider( rURL
);
216 throw ContentCreationException(
217 "No Content Provider available for URL: " + rURL
,
218 Reference
< XInterface
>(),
219 ContentCreationError_NO_CONTENT_PROVIDER
);
223 //=========================================================================
224 static Reference
< XContentIdentifier
> getContentIdentifier(
225 const Reference
< XUniversalContentBroker
> & rBroker
,
226 const OUString
& rURL
,
228 throw ( ContentCreationException
, RuntimeException
)
230 Reference
< XContentIdentifier
> xId
231 = rBroker
->createContentIdentifier( rURL
);
238 ensureContentProviderForURL( rBroker
, rURL
);
240 throw ContentCreationException(
241 "Unable to create Content Identifier!",
242 Reference
< XInterface
>(),
243 ContentCreationError_IDENTIFIER_CREATION_FAILED
);
246 return Reference
< XContentIdentifier
>();
249 //=========================================================================
250 static Reference
< XContent
> getContent(
251 const Reference
< XUniversalContentBroker
> & rBroker
,
252 const Reference
< XContentIdentifier
> & xId
,
254 throw ( ContentCreationException
, RuntimeException
)
256 Reference
< XContent
> xContent
;
260 xContent
= rBroker
->queryContent( xId
);
262 catch ( IllegalIdentifierException
const & e
)
273 ensureContentProviderForURL( rBroker
, xId
->getContentIdentifier() );
275 throw ContentCreationException(
276 "Unable to create Content! " + msg
,
277 Reference
< XInterface
>(),
278 ContentCreationError_CONTENT_CREATION_FAILED
);
281 return Reference
< XContent
>();
284 //=========================================================================
285 //=========================================================================
287 // Content Implementation.
289 //=========================================================================
290 //=========================================================================
293 : m_xImpl( new Content_Impl
)
297 //=========================================================================
298 Content::Content( const OUString
& rURL
,
299 const Reference
< XCommandEnvironment
>& rEnv
,
300 const Reference
< XComponentContext
>& rCtx
)
301 throw ( ContentCreationException
, RuntimeException
)
303 Reference
< XUniversalContentBroker
> pBroker(
304 UniversalContentBroker::create( rCtx
) );
306 Reference
< XContentIdentifier
> xId
307 = getContentIdentifier( pBroker
, rURL
, true );
309 Reference
< XContent
> xContent
= getContent( pBroker
, xId
, true );
311 m_xImpl
= new Content_Impl( rCtx
, xContent
, rEnv
);
314 //=========================================================================
315 Content::Content( const Reference
< XContent
>& rContent
,
316 const Reference
< XCommandEnvironment
>& rEnv
,
317 const Reference
< XComponentContext
>& rCtx
)
318 throw ( ContentCreationException
, RuntimeException
)
320 m_xImpl
= new Content_Impl( rCtx
, rContent
, rEnv
);
323 //=========================================================================
324 Content::Content( const Content
& rOther
)
326 m_xImpl
= rOther
.m_xImpl
;
329 //=========================================================================
331 sal_Bool
Content::create( const OUString
& rURL
,
332 const Reference
< XCommandEnvironment
>& rEnv
,
333 const Reference
< XComponentContext
>& rCtx
,
336 Reference
< XUniversalContentBroker
> pBroker(
337 UniversalContentBroker::create( rCtx
) );
339 Reference
< XContentIdentifier
> xId
340 = getContentIdentifier( pBroker
, rURL
, false );
344 Reference
< XContent
> xContent
= getContent( pBroker
, xId
, false );
345 if ( !xContent
.is() )
349 = new Content_Impl( rCtx
, xContent
, rEnv
);
354 //=========================================================================
359 //=========================================================================
360 Content
& Content::operator=( const Content
& rOther
)
362 m_xImpl
= rOther
.m_xImpl
;
366 //=========================================================================
367 Reference
< XContent
> Content::get() const
369 return m_xImpl
->getContent();
372 //=========================================================================
373 const OUString
& Content::getURL() const
375 return m_xImpl
->getURL();
378 //=========================================================================
379 const Reference
< XCommandEnvironment
>& Content::getCommandEnvironment() const
381 return m_xImpl
->getEnvironment();
384 //=========================================================================
385 void Content::setCommandEnvironment(
386 const Reference
< XCommandEnvironment
>& xNewEnv
)
388 m_xImpl
->setEnvironment( xNewEnv
);
391 //=========================================================================
392 Reference
< XCommandInfo
> Content::getCommands()
393 throw( CommandAbortedException
, RuntimeException
, Exception
)
396 aCommand
.Name
= OUString("getCommandInfo");
397 aCommand
.Handle
= -1; // n/a
398 aCommand
.Argument
= Any();
400 Any aResult
= m_xImpl
->executeCommand( aCommand
);
402 Reference
< XCommandInfo
> xInfo
;
407 //=========================================================================
408 Reference
< XPropertySetInfo
> Content::getProperties()
409 throw( CommandAbortedException
, RuntimeException
, Exception
)
412 aCommand
.Name
= OUString("getPropertySetInfo");
413 aCommand
.Handle
= -1; // n/a
414 aCommand
.Argument
= Any();
416 Any aResult
= m_xImpl
->executeCommand( aCommand
);
418 Reference
< XPropertySetInfo
> xInfo
;
423 //=========================================================================
424 Any
Content::getPropertyValue( const OUString
& rPropertyName
)
425 throw( CommandAbortedException
, RuntimeException
, Exception
)
427 Sequence
< OUString
> aNames( 1 );
428 aNames
.getArray()[ 0 ] = rPropertyName
;
430 Sequence
< Any
> aRet
= getPropertyValues( aNames
);
431 return aRet
.getConstArray()[ 0 ];
434 //=========================================================================
435 Any
Content::setPropertyValue( const OUString
& rName
,
437 throw( CommandAbortedException
, RuntimeException
, Exception
)
439 Sequence
< OUString
> aNames( 1 );
440 aNames
.getArray()[ 0 ] = rName
;
442 Sequence
< Any
> aValues( 1 );
443 aValues
.getArray()[ 0 ] = rValue
;
445 Sequence
< Any
> aErrors
= setPropertyValues( aNames
, aValues
);
446 return aErrors
.getConstArray()[ 0 ];
449 //=========================================================================
450 Sequence
< Any
> Content::getPropertyValues(
451 const Sequence
< OUString
>& rPropertyNames
)
452 throw( CommandAbortedException
, RuntimeException
, Exception
)
454 Reference
< XRow
> xRow
= getPropertyValuesInterface( rPropertyNames
);
456 sal_Int32 nCount
= rPropertyNames
.getLength();
457 Sequence
< Any
> aValues( nCount
);
461 Any
* pValues
= aValues
.getArray();
463 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
464 pValues
[ n
] = xRow
->getObject( n
+ 1, Reference
< XNameAccess
>() );
470 //=========================================================================
471 Reference
< XRow
> Content::getPropertyValuesInterface(
472 const Sequence
< OUString
>& rPropertyNames
)
473 throw( CommandAbortedException
, RuntimeException
, Exception
)
475 sal_Int32 nCount
= rPropertyNames
.getLength();
476 Sequence
< Property
> aProps( nCount
);
477 Property
* pProps
= aProps
.getArray();
479 const OUString
* pNames
= rPropertyNames
.getConstArray();
481 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
483 Property
& rProp
= pProps
[ n
];
485 rProp
.Name
= pNames
[ n
];
486 rProp
.Handle
= -1; // n/a
488 // rProp.Attributes = ;
492 aCommand
.Name
= OUString("getPropertyValues");
493 aCommand
.Handle
= -1; // n/a
494 aCommand
.Argument
<<= aProps
;
496 Any aResult
= m_xImpl
->executeCommand( aCommand
);
498 Reference
< XRow
> xRow
;
503 //=========================================================================
504 Sequence
< Any
> Content::setPropertyValues(
505 const Sequence
< OUString
>& rPropertyNames
,
506 const Sequence
< Any
>& rValues
)
507 throw( CommandAbortedException
, RuntimeException
, Exception
)
509 if ( rPropertyNames
.getLength() != rValues
.getLength() )
511 ucbhelper::cancelCommandExecution(
512 makeAny( IllegalArgumentException(
514 "Length of property names sequence and value "
515 "sequence are unequal!" ),
518 m_xImpl
->getEnvironment() );
522 sal_Int32 nCount
= rValues
.getLength();
523 Sequence
< PropertyValue
> aProps( nCount
);
524 PropertyValue
* pProps
= aProps
.getArray();
526 const OUString
* pNames
= rPropertyNames
.getConstArray();
527 const Any
* pValues
= rValues
.getConstArray();
529 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
531 PropertyValue
& rProp
= pProps
[ n
];
533 rProp
.Name
= pNames
[ n
];
534 rProp
.Handle
= -1; // n/a
535 rProp
.Value
= pValues
[ n
];
540 aCommand
.Name
= OUString("setPropertyValues");
541 aCommand
.Handle
= -1; // n/a
542 aCommand
.Argument
<<= aProps
;
544 Any aResult
= m_xImpl
->executeCommand( aCommand
);
546 Sequence
< Any
> aErrors
;
551 //=========================================================================
552 Any
Content::executeCommand( const OUString
& rCommandName
,
553 const Any
& rCommandArgument
)
554 throw( CommandAbortedException
, RuntimeException
, Exception
)
557 aCommand
.Name
= rCommandName
;
558 aCommand
.Handle
= -1; // n/a
559 aCommand
.Argument
= rCommandArgument
;
561 return m_xImpl
->executeCommand( aCommand
);
564 //=========================================================================
565 Any
Content::createCursorAny( const Sequence
< OUString
>& rPropertyNames
,
566 ResultSetInclude eMode
)
567 throw( CommandAbortedException
, RuntimeException
, Exception
)
569 sal_Int32 nCount
= rPropertyNames
.getLength();
570 Sequence
< Property
> aProps( nCount
);
571 Property
* pProps
= aProps
.getArray();
572 const OUString
* pNames
= rPropertyNames
.getConstArray();
573 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
575 Property
& rProp
= pProps
[ n
];
576 rProp
.Name
= pNames
[ n
];
577 rProp
.Handle
= -1; // n/a
580 OpenCommandArgument2 aArg
;
581 aArg
.Mode
= ( eMode
== INCLUDE_FOLDERS_ONLY
)
583 : ( eMode
== INCLUDE_DOCUMENTS_ONLY
)
584 ? OpenMode::DOCUMENTS
: OpenMode::ALL
;
585 aArg
.Priority
= 0; // unused
586 aArg
.Sink
= Reference
< XInterface
>(); // unused
587 aArg
.Properties
= aProps
;
590 aCommand
.Name
= OUString("open");
591 aCommand
.Handle
= -1; // n/a
592 aCommand
.Argument
<<= aArg
;
594 return m_xImpl
->executeCommand( aCommand
);
597 //=========================================================================
598 Reference
< XResultSet
> Content::createCursor(
599 const Sequence
< OUString
>& rPropertyNames
,
600 ResultSetInclude eMode
)
601 throw( CommandAbortedException
, RuntimeException
, Exception
)
603 Any aCursorAny
= createCursorAny( rPropertyNames
, eMode
);
605 Reference
< XDynamicResultSet
> xDynSet
;
606 Reference
< XResultSet
> aResult
;
608 aCursorAny
>>= xDynSet
;
610 aResult
= xDynSet
->getStaticResultSet();
612 OSL_ENSURE( aResult
.is(), "Content::createCursor - no cursor!" );
616 // Former, the open command directly returned a XResultSet.
617 aCursorAny
>>= aResult
;
619 OSL_ENSURE( !aResult
.is(),
620 "Content::createCursor - open-Command must "
621 "return a Reference< XDynnamicResultSet >!" );
627 //=========================================================================
628 Reference
< XDynamicResultSet
> Content::createDynamicCursor(
629 const Sequence
< OUString
>& rPropertyNames
,
630 ResultSetInclude eMode
)
631 throw( CommandAbortedException
, RuntimeException
, Exception
)
633 Reference
< XDynamicResultSet
> aResult
;
634 createCursorAny( rPropertyNames
, eMode
) >>= aResult
;
636 OSL_ENSURE( aResult
.is(), "Content::createDynamicCursor - no cursor!" );
641 //=========================================================================
642 Reference
< XResultSet
> Content::createSortedCursor(
643 const Sequence
< OUString
>& rPropertyNames
,
644 const Sequence
< NumberedSortingInfo
>& rSortInfo
,
645 Reference
< XAnyCompareFactory
> rAnyCompareFactory
,
646 ResultSetInclude eMode
)
647 throw( CommandAbortedException
, RuntimeException
, Exception
)
649 Reference
< XResultSet
> aResult
;
650 Reference
< XDynamicResultSet
> aDynSet
;
652 Any aCursorAny
= createCursorAny( rPropertyNames
, eMode
);
654 aCursorAny
>>= aDynSet
;
658 Reference
< XDynamicResultSet
> aDynResult
;
660 if( m_xImpl
->getComponentContext().is() )
662 Reference
< XSortedDynamicResultSetFactory
> aSortFactory
=
663 SortedDynamicResultSetFactory::create( m_xImpl
->getComponentContext());
665 aDynResult
= aSortFactory
->createSortedDynamicResultSet( aDynSet
,
667 rAnyCompareFactory
);
670 OSL_ENSURE( aDynResult
.is(), "Content::createSortedCursor - no sorted cursor!\n" );
672 if( aDynResult
.is() )
673 aResult
= aDynResult
->getStaticResultSet();
675 aResult
= aDynSet
->getStaticResultSet();
678 OSL_ENSURE( aResult
.is(), "Content::createSortedCursor - no cursor!" );
682 // Former, the open command directly returned a XResultSet.
683 aCursorAny
>>= aResult
;
685 OSL_ENSURE( !aResult
.is(),
686 "Content::createCursor - open-Command must "
687 "return a Reference< XDynnamicResultSet >!" );
693 //=========================================================================
694 Reference
< XInputStream
> Content::openStream()
695 throw( CommandAbortedException
, RuntimeException
, Exception
)
698 return Reference
< XInputStream
>();
700 Reference
< XActiveDataSink
> xSink
= new ActiveDataSink
;
702 OpenCommandArgument2 aArg
;
703 aArg
.Mode
= OpenMode::DOCUMENT
;
704 aArg
.Priority
= 0; // unused
706 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
709 aCommand
.Name
= OUString("open");
710 aCommand
.Handle
= -1; // n/a
711 aCommand
.Argument
<<= aArg
;
713 m_xImpl
->executeCommand( aCommand
);
715 return xSink
->getInputStream();
718 //=========================================================================
719 Reference
< XInputStream
> Content::openStreamNoLock()
720 throw( CommandAbortedException
, RuntimeException
, Exception
)
723 return Reference
< XInputStream
>();
725 Reference
< XActiveDataSink
> xSink
= new ActiveDataSink
;
727 OpenCommandArgument2 aArg
;
728 aArg
.Mode
= OpenMode::DOCUMENT_SHARE_DENY_NONE
;
729 aArg
.Priority
= 0; // unused
731 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
734 aCommand
.Name
= OUString("open");
735 aCommand
.Handle
= -1; // n/a
736 aCommand
.Argument
<<= aArg
;
738 m_xImpl
->executeCommand( aCommand
);
740 return xSink
->getInputStream();
743 //=========================================================================
744 Reference
< XStream
> Content::openWriteableStream()
745 throw( CommandAbortedException
, RuntimeException
, Exception
)
748 return Reference
< XStream
>();
750 Reference
< XActiveDataStreamer
> xStreamer
= new ActiveDataStreamer
;
752 OpenCommandArgument2 aArg
;
753 aArg
.Mode
= OpenMode::DOCUMENT
;
754 aArg
.Priority
= 0; // unused
755 aArg
.Sink
= xStreamer
;
756 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
759 aCommand
.Name
= OUString("open");
760 aCommand
.Handle
= -1; // n/a
761 aCommand
.Argument
<<= aArg
;
763 m_xImpl
->executeCommand( aCommand
);
765 return xStreamer
->getStream();
768 //=========================================================================
769 Reference
< XStream
> Content::openWriteableStreamNoLock()
770 throw( CommandAbortedException
, RuntimeException
, Exception
)
773 return Reference
< XStream
>();
775 Reference
< XActiveDataStreamer
> xStreamer
= new ActiveDataStreamer
;
777 OpenCommandArgument2 aArg
;
778 aArg
.Mode
= OpenMode::DOCUMENT_SHARE_DENY_NONE
;
779 aArg
.Priority
= 0; // unused
780 aArg
.Sink
= xStreamer
;
781 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
784 aCommand
.Name
= OUString("open");
785 aCommand
.Handle
= -1; // n/a
786 aCommand
.Argument
<<= aArg
;
788 m_xImpl
->executeCommand( aCommand
);
790 return xStreamer
->getStream();
793 //=========================================================================
794 sal_Bool
Content::openStream( const Reference
< XActiveDataSink
>& rSink
)
795 throw( CommandAbortedException
, RuntimeException
, Exception
)
800 OpenCommandArgument2 aArg
;
801 aArg
.Mode
= OpenMode::DOCUMENT
;
802 aArg
.Priority
= 0; // unused
804 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
807 aCommand
.Name
= OUString("open");
808 aCommand
.Handle
= -1; // n/a
809 aCommand
.Argument
<<= aArg
;
811 m_xImpl
->executeCommand( aCommand
);
816 //=========================================================================
817 sal_Bool
Content::openStream( const Reference
< XOutputStream
>& rStream
)
818 throw( CommandAbortedException
, RuntimeException
, Exception
)
823 OpenCommandArgument2 aArg
;
824 aArg
.Mode
= OpenMode::DOCUMENT
;
825 aArg
.Priority
= 0; // unused
827 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
830 aCommand
.Name
= OUString("open");
831 aCommand
.Handle
= -1; // n/a
832 aCommand
.Argument
<<= aArg
;
834 m_xImpl
->executeCommand( aCommand
);
839 //=========================================================================
840 void Content::writeStream( const Reference
< XInputStream
>& rStream
,
841 sal_Bool bReplaceExisting
)
842 throw( CommandAbortedException
, RuntimeException
, Exception
)
844 InsertCommandArgument aArg
;
845 aArg
.Data
= rStream
.is() ? rStream
: new EmptyInputStream
;
846 aArg
.ReplaceExisting
= bReplaceExisting
;
849 aCommand
.Name
= OUString("insert");
850 aCommand
.Handle
= -1; // n/a
851 aCommand
.Argument
<<= aArg
;
853 m_xImpl
->executeCommand( aCommand
);
858 //=========================================================================
859 Sequence
< ContentInfo
> Content::queryCreatableContentsInfo()
860 throw( CommandAbortedException
, RuntimeException
, Exception
)
862 // First, try it using "CreatableContentsInfo" property -> the "new" way.
863 Sequence
< ContentInfo
> aInfo
;
864 if ( getPropertyValue(
865 OUString("CreatableContentsInfo") )
869 // Second, try it using XContentCreator interface -> the "old" way (not
870 // providing the chance to supply an XCommandEnvironment.
871 Reference
< XContentCreator
> xCreator( m_xImpl
->getContent(), UNO_QUERY
);
873 aInfo
= xCreator
->queryCreatableContentsInfo();
878 //=========================================================================
879 sal_Bool
Content::insertNewContent( const OUString
& rContentType
,
880 const Sequence
< OUString
>&
882 const Sequence
< Any
>& rPropertyValues
,
883 Content
& rNewContent
)
884 throw( CommandAbortedException
, RuntimeException
, Exception
)
886 return insertNewContent( rContentType
,
889 new EmptyInputStream
,
893 //=========================================================================
894 sal_Bool
Content::insertNewContent( const OUString
& rContentType
,
895 const Sequence
< OUString
>&
897 const Sequence
< Any
>& rPropertyValues
,
898 const Reference
< XInputStream
>& rData
,
899 Content
& rNewContent
)
900 throw( CommandAbortedException
, RuntimeException
, Exception
)
902 if ( rContentType
.isEmpty() )
905 // First, try it using "createNewContent" command -> the "new" way.
907 aInfo
.Type
= rContentType
;
908 aInfo
.Attributes
= 0;
911 aCommand
.Name
= OUString("createNewContent");
912 aCommand
.Handle
= -1; // n/a
913 aCommand
.Argument
<<= aInfo
;
915 Reference
< XContent
> xNew
;
918 m_xImpl
->executeCommand( aCommand
) >>= xNew
;
920 catch ( RuntimeException
const & )
924 catch ( Exception
const & )
930 // Second, try it using XContentCreator interface -> the "old"
931 // way (not providing the chance to supply an XCommandEnvironment.
932 Reference
< XContentCreator
> xCreator( m_xImpl
->getContent(), UNO_QUERY
);
934 if ( !xCreator
.is() )
937 xNew
= xCreator
->createNewContent( aInfo
);
944 xNew
, m_xImpl
->getEnvironment(), m_xImpl
->getComponentContext() );
945 aNewContent
.setPropertyValues( rPropertyNames
, rPropertyValues
);
946 aNewContent
.executeCommand( OUString("insert"),
948 InsertCommandArgument(
949 rData
.is() ? rData
: new EmptyInputStream
,
950 sal_False
/* ReplaceExisting */ ) ) );
951 aNewContent
.m_xImpl
->inserted();
953 rNewContent
= aNewContent
;
957 //=========================================================================
958 sal_Bool
Content::transferContent( const Content
& rSourceContent
,
959 InsertOperation eOperation
,
960 const OUString
& rTitle
,
961 const sal_Int32 nNameClashAction
,
962 const OUString
& rMimeType
,
964 const OUString
& rVersionComment
,
965 OUString
* pResultURL
)
966 throw( CommandAbortedException
, RuntimeException
, Exception
)
968 Reference
< XUniversalContentBroker
> pBroker(
969 UniversalContentBroker::create( m_xImpl
->getComponentContext() ) );
971 // Execute command "globalTransfer" at UCB.
973 TransferCommandOperation eTransOp
= TransferCommandOperation();
974 OUString
sCommand( "globalTransfer" );
975 bool bCheckIn
= false;
976 switch ( eOperation
)
978 case InsertOperation_COPY
:
979 eTransOp
= TransferCommandOperation_COPY
;
982 case InsertOperation_MOVE
:
983 eTransOp
= TransferCommandOperation_MOVE
;
986 case InsertOperation_LINK
:
987 eTransOp
= TransferCommandOperation_LINK
;
990 case InsertOperation_CHECKIN
:
991 eTransOp
= TransferCommandOperation_COPY
;
992 sCommand
= OUString( "checkin" );
997 ucbhelper::cancelCommandExecution(
998 makeAny( IllegalArgumentException(
1000 "Unknown transfer operation!" ),
1003 m_xImpl
->getEnvironment() );
1007 aCommand
.Name
= sCommand
;
1008 aCommand
.Handle
= -1; // n/a
1012 GlobalTransferCommandArgument2
aTransferArg(
1014 rSourceContent
.getURL(), // SourceURL
1015 getURL(), // TargetFolderURL,
1019 aCommand
.Argument
<<= aTransferArg
;
1023 CheckinArgument
aCheckinArg( bMajorVersion
, rVersionComment
,
1024 rSourceContent
.getURL(), getURL(), rTitle
, rMimeType
);
1025 aCommand
.Argument
<<= aCheckinArg
;
1028 Any aRet
= pBroker
->execute( aCommand
, 0, m_xImpl
->getEnvironment() );
1029 if ( pResultURL
!= NULL
)
1030 aRet
>>= *pResultURL
;
1034 //=========================================================================
1035 sal_Bool
Content::isFolder()
1036 throw( CommandAbortedException
, RuntimeException
, Exception
)
1038 sal_Bool bFolder
= sal_False
;
1039 if ( getPropertyValue( OUString("IsFolder") )
1043 ucbhelper::cancelCommandExecution(
1044 makeAny( UnknownPropertyException(
1046 "Unable to retrieve value of property 'IsFolder'!" ),
1048 m_xImpl
->getEnvironment() );
1050 // Unreachable - cancelCommandExecution always throws an exception.
1051 // But some compilers complain...
1055 //=========================================================================
1056 sal_Bool
Content::isDocument()
1057 throw( CommandAbortedException
, RuntimeException
, Exception
)
1059 sal_Bool bDoc
= sal_False
;
1060 if ( getPropertyValue( OUString("IsDocument") )
1064 ucbhelper::cancelCommandExecution(
1065 makeAny( UnknownPropertyException(
1067 "Unable to retrieve value of property 'IsDocument'!" ),
1069 m_xImpl
->getEnvironment() );
1071 // Unreachable - cancelCommandExecution always throws an exception,
1072 // But some compilers complain...
1076 //=========================================================================
1077 //=========================================================================
1079 // Content_Impl Implementation.
1081 //=========================================================================
1082 //=========================================================================
1084 Content_Impl::Content_Impl( const Reference
< XComponentContext
>& rCtx
,
1085 const Reference
< XContent
>& rContent
,
1086 const Reference
< XCommandEnvironment
>& rEnv
)
1088 m_xContent( rContent
),
1092 if ( m_xContent
.is() )
1094 m_xContentEventListener
= new ContentEventListener_Impl( *this );
1095 m_xContent
->addContentEventListener( m_xContentEventListener
);
1097 #if OSL_DEBUG_LEVEL > 1
1098 // Only done on demand in product version for performance reasons,
1099 // but a nice debug helper.
1105 //=========================================================================
1106 void Content_Impl::reinit( const Reference
< XContent
>& xContent
)
1108 osl::MutexGuard
aGuard( m_aMutex
);
1110 m_xCommandProcessor
= 0;
1112 // #92581# - Don't reset m_aURL!!!
1114 if ( m_xContent
.is() )
1118 m_xContent
->removeContentEventListener( m_xContentEventListener
);
1120 catch ( RuntimeException
const & )
1125 if ( xContent
.is() )
1127 m_xContent
= xContent
;
1128 m_xContent
->addContentEventListener( m_xContentEventListener
);
1130 #if OSL_DEBUG_LEVEL > 1
1131 // Only done on demand in product version for performance reasons,
1132 // but a nice debug helper.
1138 // We need m_xContent's URL in order to be able to create the
1139 // content object again if demanded ( --> Content_Impl::getContent() )
1146 //=========================================================================
1148 Content_Impl::~Content_Impl()
1150 if ( m_xContent
.is() )
1154 m_xContent
->removeContentEventListener( m_xContentEventListener
);
1156 catch ( RuntimeException
const & )
1162 //=========================================================================
1163 void Content_Impl::disposing( const EventObject
& Source
)
1165 Reference
<XContent
> xContent
;
1168 osl::MutexGuard
aGuard( m_aMutex
);
1169 if(Source
.Source
!= m_xContent
)
1172 xContent
= m_xContent
;
1174 m_aURL
= OUString();
1175 m_xCommandProcessor
= 0;
1179 if ( xContent
.is() )
1183 xContent
->removeContentEventListener( m_xContentEventListener
);
1185 catch ( RuntimeException
const & )
1191 //=========================================================================
1192 const OUString
& Content_Impl::getURL() const
1194 if ( m_aURL
.isEmpty() && m_xContent
.is() )
1196 osl::MutexGuard
aGuard( m_aMutex
);
1198 if ( m_aURL
.isEmpty() && m_xContent
.is() )
1200 Reference
< XContentIdentifier
> xId
= m_xContent
->getIdentifier();
1202 m_aURL
= xId
->getContentIdentifier();
1209 //=========================================================================
1210 Reference
< XContent
> Content_Impl::getContent()
1212 if ( !m_xContent
.is() && !m_aURL
.isEmpty() )
1214 osl::MutexGuard
aGuard( m_aMutex
);
1216 if ( !m_xContent
.is() && !m_aURL
.isEmpty() )
1218 Reference
< XUniversalContentBroker
> pBroker(
1219 UniversalContentBroker::create( getComponentContext() ) );
1221 OSL_ENSURE( pBroker
->queryContentProviders().getLength(),
1222 "Content Broker not configured (no providers)!" );
1224 Reference
< XContentIdentifier
> xId
1225 = pBroker
->createContentIdentifier( m_aURL
);
1227 OSL_ENSURE( xId
.is(), "No Content Identifier!" );
1233 m_xContent
= pBroker
->queryContent( xId
);
1235 catch ( IllegalIdentifierException
const & )
1239 if ( m_xContent
.is() )
1240 m_xContent
->addContentEventListener(
1241 m_xContentEventListener
);
1249 //=========================================================================
1250 Reference
< XCommandProcessor
> Content_Impl::getCommandProcessor()
1252 if ( !m_xCommandProcessor
.is() )
1254 osl::MutexGuard
aGuard( m_aMutex
);
1256 if ( !m_xCommandProcessor
.is() )
1258 = Reference
< XCommandProcessor
>( getContent(), UNO_QUERY
);
1261 return m_xCommandProcessor
;
1264 //=========================================================================
1265 Any
Content_Impl::executeCommand( const Command
& rCommand
)
1267 Reference
< XCommandProcessor
> xProc
= getCommandProcessor();
1272 return xProc
->execute( rCommand
, 0, m_xEnv
);
1275 //=========================================================================
1276 inline const Reference
< XCommandEnvironment
>&
1277 Content_Impl::getEnvironment() const
1282 //=========================================================================
1283 inline void Content_Impl::setEnvironment(
1284 const Reference
< XCommandEnvironment
>& xNewEnv
)
1286 osl::MutexGuard
aGuard( m_aMutex
);
1290 //=========================================================================
1291 void Content_Impl::inserted()
1293 // URL might have changed during 'insert' => recalculate in next getURL()
1294 osl::MutexGuard
aGuard( m_aMutex
);
1295 m_aURL
= OUString();
1298 //=========================================================================
1299 //=========================================================================
1301 // ContentEventListener_Impl Implementation.
1303 //=========================================================================
1304 //=========================================================================
1306 //=========================================================================
1308 // XInterface methods.
1310 //=========================================================================
1312 XINTERFACE_IMPL_2( ContentEventListener_Impl
,
1313 XContentEventListener
,
1314 XEventListener
); /* base of XContentEventListener */
1316 //=========================================================================
1318 // XContentEventListener methods.
1320 //=========================================================================
1323 void SAL_CALL
ContentEventListener_Impl::contentEvent( const ContentEvent
& evt
)
1324 throw( RuntimeException
)
1326 if ( evt
.Source
== m_rContent
.m_xContent
)
1328 switch ( evt
.Action
)
1330 case ContentAction::DELETED
:
1331 m_rContent
.reinit( Reference
< XContent
>() );
1334 case ContentAction::EXCHANGED
:
1335 m_rContent
.reinit( evt
.Content
);
1344 //=========================================================================
1346 // XEventListenr methods.
1348 //=========================================================================
1351 void SAL_CALL
ContentEventListener_Impl::disposing( const EventObject
& Source
)
1352 throw( RuntimeException
)
1354 m_rContent
.disposing(Source
);
1357 } /* namespace ucbhelper */
1359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */