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 <sal/log.hxx>
27 #include <salhelper/simplereferenceobject.hxx>
28 #include <cppuhelper/weak.hxx>
30 #include <cppuhelper/implbase1.hxx>
31 #include <com/sun/star/ucb/CheckinArgument.hpp>
32 #include <com/sun/star/ucb/ContentCreationError.hpp>
33 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
34 #include <com/sun/star/ucb/XCommandInfo.hpp>
35 #include <com/sun/star/ucb/XCommandProcessor.hpp>
36 #include <com/sun/star/ucb/Command.hpp>
37 #include <com/sun/star/ucb/CommandInfo.hpp>
38 #include <com/sun/star/ucb/ContentAction.hpp>
39 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
40 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
41 #include <com/sun/star/ucb/GlobalTransferCommandArgument2.hpp>
42 #include <com/sun/star/ucb/NameClash.hpp>
43 #include <com/sun/star/ucb/OpenMode.hpp>
44 #include <com/sun/star/ucb/XContentCreator.hpp>
45 #include <com/sun/star/ucb/XContentEventListener.hpp>
46 #include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
47 #include <com/sun/star/ucb/XContentProvider.hpp>
48 #include <com/sun/star/ucb/XContentProviderManager.hpp>
49 #include <com/sun/star/ucb/XDynamicResultSet.hpp>
50 #include <com/sun/star/ucb/SortedDynamicResultSetFactory.hpp>
51 #include <com/sun/star/ucb/UniversalContentBroker.hpp>
52 #include <com/sun/star/ucb/XUniversalContentBroker.hpp>
53 #include <com/sun/star/beans/XPropertySetInfo.hpp>
54 #include <com/sun/star/beans/Property.hpp>
55 #include <com/sun/star/beans/PropertyValue.hpp>
56 #include <com/sun/star/sdbc/XResultSet.hpp>
57 #include <com/sun/star/sdbc/XRow.hpp>
58 #include <com/sun/star/lang/IllegalArgumentException.hpp>
59 #include <com/sun/star/beans/UnknownPropertyException.hpp>
60 #include <ucbhelper/macros.hxx>
61 #include <ucbhelper/content.hxx>
62 #include <ucbhelper/activedatasink.hxx>
63 #include <ucbhelper/activedatastreamer.hxx>
64 #include <ucbhelper/interactionrequest.hxx>
65 #include <ucbhelper/cancelcommandexecution.hxx>
67 using namespace com::sun::star::container
;
68 using namespace com::sun::star::beans
;
69 using namespace com::sun::star::io
;
70 using namespace com::sun::star::lang
;
71 using namespace com::sun::star::sdbc
;
72 using namespace com::sun::star::task
;
73 using namespace com::sun::star::ucb
;
74 using namespace com::sun::star::uno
;
79 class EmptyInputStream
: public ::cppu::WeakImplHelper1
< XInputStream
>
82 virtual sal_Int32 SAL_CALL
readBytes(
83 Sequence
< sal_Int8
> & data
, sal_Int32 nBytesToRead
)
84 throw (IOException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
85 virtual sal_Int32 SAL_CALL
readSomeBytes(
86 Sequence
< sal_Int8
> & data
, sal_Int32 nMaxBytesToRead
)
87 throw (IOException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
88 virtual void SAL_CALL
skipBytes( sal_Int32 nBytesToSkip
)
89 throw (IOException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
90 virtual sal_Int32 SAL_CALL
available()
91 throw (IOException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
92 virtual void SAL_CALL
closeInput()
93 throw (IOException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
96 sal_Int32
EmptyInputStream::readBytes(
97 Sequence
< sal_Int8
> & data
, sal_Int32
)
98 throw (IOException
, RuntimeException
, std::exception
)
104 sal_Int32
EmptyInputStream::readSomeBytes(
105 Sequence
< sal_Int8
> & data
, sal_Int32
)
106 throw (IOException
, RuntimeException
, std::exception
)
112 void EmptyInputStream::skipBytes( sal_Int32
)
113 throw (IOException
, RuntimeException
, std::exception
)
117 sal_Int32
EmptyInputStream::available()
118 throw (IOException
, RuntimeException
, std::exception
)
123 void EmptyInputStream::closeInput()
124 throw (IOException
, RuntimeException
, std::exception
)
132 // class ContentEventListener_Impl.
137 class ContentEventListener_Impl
: public cppu::OWeakObject
,
138 public XContentEventListener
140 Content_Impl
& m_rContent
;
143 ContentEventListener_Impl( Content_Impl
& rContent
)
144 : m_rContent( rContent
) {}
147 virtual css::uno::Any SAL_CALL
queryInterface( const css::uno::Type
& rType
)
148 throw( css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
149 virtual void SAL_CALL
acquire()
150 throw() SAL_OVERRIDE
;
151 virtual void SAL_CALL
release()
152 throw() SAL_OVERRIDE
;
154 // XContentEventListener
155 virtual void SAL_CALL
contentEvent( const ContentEvent
& evt
)
156 throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
158 // XEventListener ( base of XContentEventListener )
159 virtual void SAL_CALL
disposing( const EventObject
& Source
)
160 throw( RuntimeException
, std::exception
) SAL_OVERRIDE
;
166 // class Content_Impl.
171 class Content_Impl
: public salhelper::SimpleReferenceObject
173 friend class ContentEventListener_Impl
;
175 mutable OUString m_aURL
;
176 Reference
< XComponentContext
> m_xCtx
;
177 Reference
< XContent
> m_xContent
;
178 Reference
< XCommandProcessor
> m_xCommandProcessor
;
179 Reference
< XCommandEnvironment
> m_xEnv
;
180 Reference
< XContentEventListener
> m_xContentEventListener
;
181 mutable osl::Mutex m_aMutex
;
184 void reinit( const Reference
< XContent
>& xContent
);
185 void disposing(const EventObject
& Source
);
189 Content_Impl( const Reference
< XComponentContext
>& rCtx
,
190 const Reference
< XContent
>& rContent
,
191 const Reference
< XCommandEnvironment
>& rEnv
);
193 virtual ~Content_Impl();
195 const OUString
& getURL() const;
196 Reference
< XContent
> getContent();
197 Reference
< XCommandProcessor
> getCommandProcessor();
198 Reference
< XComponentContext
> getComponentContext()
199 { assert(m_xCtx
.is()); return m_xCtx
; }
201 Any
executeCommand( const Command
& rCommand
);
203 inline const Reference
< XCommandEnvironment
>& getEnvironment() const;
204 inline void setEnvironment(
205 const Reference
< XCommandEnvironment
>& xNewEnv
);
214 static void ensureContentProviderForURL( const Reference
< XUniversalContentBroker
>& rBroker
,
215 const OUString
& rURL
)
216 throw ( ContentCreationException
, RuntimeException
)
218 Reference
< XContentProvider
> xProv
219 = rBroker
->queryContentProvider( rURL
);
222 throw ContentCreationException(
223 "No Content Provider available for URL: " + rURL
,
224 Reference
< XInterface
>(),
225 ContentCreationError_NO_CONTENT_PROVIDER
);
230 static Reference
< XContentIdentifier
> getContentIdentifierThrow(
231 const Reference
< XUniversalContentBroker
> & rBroker
,
232 const OUString
& rURL
)
233 throw (ContentCreationException
, RuntimeException
)
235 Reference
< XContentIdentifier
> xId
236 = rBroker
->createContentIdentifier( rURL
);
240 ensureContentProviderForURL( rBroker
, rURL
);
242 throw ContentCreationException(
243 "Unable to create Content Identifier!",
244 Reference
< XInterface
>(),
245 ContentCreationError_IDENTIFIER_CREATION_FAILED
);
251 static Reference
< XContentIdentifier
> getContentIdentifierNoThrow(
252 const Reference
< XUniversalContentBroker
> & rBroker
,
253 const OUString
& rURL
)
254 throw (RuntimeException
)
256 return rBroker
->createContentIdentifier(rURL
);
259 static Reference
< XContent
> getContentThrow(
260 const Reference
< XUniversalContentBroker
> & rBroker
,
261 const Reference
< XContentIdentifier
> & xId
)
262 throw ( ContentCreationException
, RuntimeException
)
264 Reference
< XContent
> xContent
;
268 xContent
= rBroker
->queryContent( xId
);
270 catch ( IllegalIdentifierException
const & e
)
276 if ( !xContent
.is() )
278 ensureContentProviderForURL( rBroker
, xId
->getContentIdentifier() );
280 throw ContentCreationException(
281 "Unable to create Content for <" + xId
->getContentIdentifier() + ">: " + msg
,
282 Reference
< XInterface
>(),
283 ContentCreationError_CONTENT_CREATION_FAILED
);
290 static Reference
< XContent
> getContentNoThrow(
291 const Reference
< XUniversalContentBroker
> & rBroker
,
292 const Reference
< XContentIdentifier
> & xId
)
293 throw ( RuntimeException
)
295 Reference
< XContent
> xContent
;
298 xContent
= rBroker
->queryContent( xId
);
300 catch ( IllegalIdentifierException
const & e
)
302 SAL_WARN("ucbhelper", "getContentNoThrow: exception: " << e
.Message
);
311 // Content Implementation.
317 : m_xImpl( new Content_Impl
)
322 Content::Content( const OUString
& rURL
,
323 const Reference
< XCommandEnvironment
>& rEnv
,
324 const Reference
< XComponentContext
>& rCtx
)
325 throw ( ContentCreationException
, RuntimeException
)
327 Reference
< XUniversalContentBroker
> pBroker(
328 UniversalContentBroker::create( rCtx
) );
330 Reference
< XContentIdentifier
> xId
331 = getContentIdentifierThrow(pBroker
, rURL
);
333 Reference
< XContent
> xContent
= getContentThrow(pBroker
, xId
);
335 m_xImpl
= new Content_Impl( rCtx
, xContent
, rEnv
);
339 Content::Content( const Reference
< XContent
>& rContent
,
340 const Reference
< XCommandEnvironment
>& rEnv
,
341 const Reference
< XComponentContext
>& rCtx
)
342 throw ( ContentCreationException
, RuntimeException
)
344 m_xImpl
= new Content_Impl( rCtx
, rContent
, rEnv
);
348 Content::Content( const Content
& rOther
)
350 m_xImpl
= rOther
.m_xImpl
;
355 bool Content::create( const OUString
& rURL
,
356 const Reference
< XCommandEnvironment
>& rEnv
,
357 const Reference
< XComponentContext
>& rCtx
,
360 Reference
< XUniversalContentBroker
> pBroker(
361 UniversalContentBroker::create( rCtx
) );
363 Reference
< XContentIdentifier
> xId
364 = getContentIdentifierNoThrow(pBroker
, rURL
);
368 Reference
< XContent
> xContent
= getContentNoThrow(pBroker
, xId
);
369 if ( !xContent
.is() )
373 = new Content_Impl( rCtx
, xContent
, rEnv
);
384 Content
& Content::operator=( const Content
& rOther
)
386 m_xImpl
= rOther
.m_xImpl
;
391 Reference
< XContent
> Content::get() const
393 return m_xImpl
->getContent();
397 const OUString
& Content::getURL() const
399 return m_xImpl
->getURL();
403 const Reference
< XCommandEnvironment
>& Content::getCommandEnvironment() const
405 return m_xImpl
->getEnvironment();
409 void Content::setCommandEnvironment(
410 const Reference
< XCommandEnvironment
>& xNewEnv
)
412 m_xImpl
->setEnvironment( xNewEnv
);
416 Reference
< XCommandInfo
> Content::getCommands()
417 throw( CommandAbortedException
, RuntimeException
, Exception
)
420 aCommand
.Name
= "getCommandInfo";
421 aCommand
.Handle
= -1; // n/a
422 aCommand
.Argument
= Any();
424 Any aResult
= m_xImpl
->executeCommand( aCommand
);
426 Reference
< XCommandInfo
> xInfo
;
432 Reference
< XPropertySetInfo
> Content::getProperties()
433 throw( CommandAbortedException
, RuntimeException
, Exception
)
436 aCommand
.Name
= "getPropertySetInfo";
437 aCommand
.Handle
= -1; // n/a
438 aCommand
.Argument
= Any();
440 Any aResult
= m_xImpl
->executeCommand( aCommand
);
442 Reference
< XPropertySetInfo
> xInfo
;
448 Any
Content::getPropertyValue( const OUString
& rPropertyName
)
449 throw( CommandAbortedException
, RuntimeException
, Exception
)
451 Sequence
< OUString
> aNames( 1 );
452 aNames
.getArray()[ 0 ] = rPropertyName
;
454 Sequence
< Any
> aRet
= getPropertyValues( aNames
);
455 return aRet
.getConstArray()[ 0 ];
459 Any
Content::setPropertyValue( const OUString
& rName
,
461 throw( CommandAbortedException
, RuntimeException
, Exception
)
463 Sequence
< OUString
> aNames( 1 );
464 aNames
.getArray()[ 0 ] = rName
;
466 Sequence
< Any
> aValues( 1 );
467 aValues
.getArray()[ 0 ] = rValue
;
469 Sequence
< Any
> aErrors
= setPropertyValues( aNames
, aValues
);
470 return aErrors
.getConstArray()[ 0 ];
474 Sequence
< Any
> Content::getPropertyValues(
475 const Sequence
< OUString
>& rPropertyNames
)
476 throw( CommandAbortedException
, RuntimeException
, Exception
)
478 Reference
< XRow
> xRow
= getPropertyValuesInterface( rPropertyNames
);
480 sal_Int32 nCount
= rPropertyNames
.getLength();
481 Sequence
< Any
> aValues( nCount
);
485 Any
* pValues
= aValues
.getArray();
487 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
488 pValues
[ n
] = xRow
->getObject( n
+ 1, Reference
< XNameAccess
>() );
495 Reference
< XRow
> Content::getPropertyValuesInterface(
496 const Sequence
< OUString
>& rPropertyNames
)
497 throw( CommandAbortedException
, RuntimeException
, Exception
)
499 sal_Int32 nCount
= rPropertyNames
.getLength();
500 Sequence
< Property
> aProps( nCount
);
501 Property
* pProps
= aProps
.getArray();
503 const OUString
* pNames
= rPropertyNames
.getConstArray();
505 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
507 Property
& rProp
= pProps
[ n
];
509 rProp
.Name
= pNames
[ n
];
510 rProp
.Handle
= -1; // n/a
512 // rProp.Attributes = ;
516 aCommand
.Name
= "getPropertyValues";
517 aCommand
.Handle
= -1; // n/a
518 aCommand
.Argument
<<= aProps
;
520 Any aResult
= m_xImpl
->executeCommand( aCommand
);
522 Reference
< XRow
> xRow
;
528 Sequence
< Any
> Content::setPropertyValues(
529 const Sequence
< OUString
>& rPropertyNames
,
530 const Sequence
< Any
>& rValues
)
531 throw( CommandAbortedException
, RuntimeException
, Exception
)
533 if ( rPropertyNames
.getLength() != rValues
.getLength() )
535 ucbhelper::cancelCommandExecution(
536 makeAny( IllegalArgumentException(
538 "Length of property names sequence and value "
539 "sequence are unequal!" ),
542 m_xImpl
->getEnvironment() );
546 sal_Int32 nCount
= rValues
.getLength();
547 Sequence
< PropertyValue
> aProps( nCount
);
548 PropertyValue
* pProps
= aProps
.getArray();
550 const OUString
* pNames
= rPropertyNames
.getConstArray();
551 const Any
* pValues
= rValues
.getConstArray();
553 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
555 PropertyValue
& rProp
= pProps
[ n
];
557 rProp
.Name
= pNames
[ n
];
558 rProp
.Handle
= -1; // n/a
559 rProp
.Value
= pValues
[ n
];
564 aCommand
.Name
= "setPropertyValues";
565 aCommand
.Handle
= -1; // n/a
566 aCommand
.Argument
<<= aProps
;
568 Any aResult
= m_xImpl
->executeCommand( aCommand
);
570 Sequence
< Any
> aErrors
;
576 Any
Content::executeCommand( const OUString
& rCommandName
,
577 const Any
& rCommandArgument
)
578 throw( CommandAbortedException
, RuntimeException
, Exception
)
581 aCommand
.Name
= rCommandName
;
582 aCommand
.Handle
= -1; // n/a
583 aCommand
.Argument
= rCommandArgument
;
585 return m_xImpl
->executeCommand( aCommand
);
589 Any
Content::createCursorAny( const Sequence
< OUString
>& rPropertyNames
,
590 ResultSetInclude eMode
)
591 throw( CommandAbortedException
, RuntimeException
, Exception
)
593 sal_Int32 nCount
= rPropertyNames
.getLength();
594 Sequence
< Property
> aProps( nCount
);
595 Property
* pProps
= aProps
.getArray();
596 const OUString
* pNames
= rPropertyNames
.getConstArray();
597 for ( sal_Int32 n
= 0; n
< nCount
; ++n
)
599 Property
& rProp
= pProps
[ n
];
600 rProp
.Name
= pNames
[ n
];
601 rProp
.Handle
= -1; // n/a
604 OpenCommandArgument2 aArg
;
605 aArg
.Mode
= ( eMode
== INCLUDE_FOLDERS_ONLY
)
607 : ( eMode
== INCLUDE_DOCUMENTS_ONLY
)
608 ? OpenMode::DOCUMENTS
: OpenMode::ALL
;
609 aArg
.Priority
= 0; // unused
610 aArg
.Sink
.clear(); // unused
611 aArg
.Properties
= aProps
;
614 aCommand
.Name
= "open";
615 aCommand
.Handle
= -1; // n/a
616 aCommand
.Argument
<<= aArg
;
618 return m_xImpl
->executeCommand( aCommand
);
622 Reference
< XResultSet
> Content::createCursor(
623 const Sequence
< OUString
>& rPropertyNames
,
624 ResultSetInclude eMode
)
625 throw( CommandAbortedException
, RuntimeException
, Exception
)
627 Any aCursorAny
= createCursorAny( rPropertyNames
, eMode
);
629 Reference
< XDynamicResultSet
> xDynSet
;
630 Reference
< XResultSet
> aResult
;
632 aCursorAny
>>= xDynSet
;
634 aResult
= xDynSet
->getStaticResultSet();
636 OSL_ENSURE( aResult
.is(), "Content::createCursor - no cursor!" );
640 // Former, the open command directly returned a XResultSet.
641 aCursorAny
>>= aResult
;
643 OSL_ENSURE( !aResult
.is(),
644 "Content::createCursor - open-Command must "
645 "return a Reference< XDynnamicResultSet >!" );
652 Reference
< XDynamicResultSet
> Content::createDynamicCursor(
653 const Sequence
< OUString
>& rPropertyNames
,
654 ResultSetInclude eMode
)
655 throw( CommandAbortedException
, RuntimeException
, Exception
)
657 Reference
< XDynamicResultSet
> aResult
;
658 createCursorAny( rPropertyNames
, eMode
) >>= aResult
;
660 OSL_ENSURE( aResult
.is(), "Content::createDynamicCursor - no cursor!" );
666 Reference
< XResultSet
> Content::createSortedCursor(
667 const Sequence
< OUString
>& rPropertyNames
,
668 const Sequence
< NumberedSortingInfo
>& rSortInfo
,
669 Reference
< XAnyCompareFactory
> rAnyCompareFactory
,
670 ResultSetInclude eMode
)
671 throw( CommandAbortedException
, RuntimeException
, Exception
)
673 Reference
< XResultSet
> aResult
;
674 Reference
< XDynamicResultSet
> aDynSet
;
676 Any aCursorAny
= createCursorAny( rPropertyNames
, eMode
);
678 aCursorAny
>>= aDynSet
;
682 Reference
< XDynamicResultSet
> aDynResult
;
684 if( m_xImpl
->getComponentContext().is() )
686 Reference
< XSortedDynamicResultSetFactory
> aSortFactory
=
687 SortedDynamicResultSetFactory::create( m_xImpl
->getComponentContext());
689 aDynResult
= aSortFactory
->createSortedDynamicResultSet( aDynSet
,
691 rAnyCompareFactory
);
694 OSL_ENSURE( aDynResult
.is(), "Content::createSortedCursor - no sorted cursor!\n" );
696 if( aDynResult
.is() )
697 aResult
= aDynResult
->getStaticResultSet();
699 aResult
= aDynSet
->getStaticResultSet();
702 OSL_ENSURE( aResult
.is(), "Content::createSortedCursor - no cursor!" );
706 // Former, the open command directly returned a XResultSet.
707 aCursorAny
>>= aResult
;
709 OSL_ENSURE( !aResult
.is(),
710 "Content::createCursor - open-Command must "
711 "return a Reference< XDynnamicResultSet >!" );
718 Reference
< XInputStream
> Content::openStream()
719 throw( CommandAbortedException
, RuntimeException
, Exception
)
722 return Reference
< XInputStream
>();
724 Reference
< XActiveDataSink
> xSink
= new ActiveDataSink
;
726 OpenCommandArgument2 aArg
;
727 aArg
.Mode
= OpenMode::DOCUMENT
;
728 aArg
.Priority
= 0; // unused
730 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
733 aCommand
.Name
= "open";
734 aCommand
.Handle
= -1; // n/a
735 aCommand
.Argument
<<= aArg
;
737 m_xImpl
->executeCommand( aCommand
);
739 return xSink
->getInputStream();
743 Reference
< XInputStream
> Content::openStreamNoLock()
744 throw( CommandAbortedException
, RuntimeException
, Exception
)
747 return Reference
< XInputStream
>();
749 Reference
< XActiveDataSink
> xSink
= new ActiveDataSink
;
751 OpenCommandArgument2 aArg
;
752 aArg
.Mode
= OpenMode::DOCUMENT_SHARE_DENY_NONE
;
753 aArg
.Priority
= 0; // unused
755 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
758 aCommand
.Name
= "open";
759 aCommand
.Handle
= -1; // n/a
760 aCommand
.Argument
<<= aArg
;
762 m_xImpl
->executeCommand( aCommand
);
764 return xSink
->getInputStream();
768 Reference
< XStream
> Content::openWriteableStream()
769 throw( CommandAbortedException
, RuntimeException
, Exception
)
772 return Reference
< XStream
>();
774 Reference
< XActiveDataStreamer
> xStreamer
= new ActiveDataStreamer
;
776 OpenCommandArgument2 aArg
;
777 aArg
.Mode
= OpenMode::DOCUMENT
;
778 aArg
.Priority
= 0; // unused
779 aArg
.Sink
= xStreamer
;
780 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
783 aCommand
.Name
= "open";
784 aCommand
.Handle
= -1; // n/a
785 aCommand
.Argument
<<= aArg
;
787 m_xImpl
->executeCommand( aCommand
);
789 return xStreamer
->getStream();
793 Reference
< XStream
> Content::openWriteableStreamNoLock()
794 throw( CommandAbortedException
, RuntimeException
, Exception
)
797 return Reference
< XStream
>();
799 Reference
< XActiveDataStreamer
> xStreamer
= new ActiveDataStreamer
;
801 OpenCommandArgument2 aArg
;
802 aArg
.Mode
= OpenMode::DOCUMENT_SHARE_DENY_NONE
;
803 aArg
.Priority
= 0; // unused
804 aArg
.Sink
= xStreamer
;
805 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
808 aCommand
.Name
= "open";
809 aCommand
.Handle
= -1; // n/a
810 aCommand
.Argument
<<= aArg
;
812 m_xImpl
->executeCommand( aCommand
);
814 return xStreamer
->getStream();
818 bool Content::openStream( const Reference
< XActiveDataSink
>& rSink
)
819 throw( CommandAbortedException
, RuntimeException
, Exception
)
824 OpenCommandArgument2 aArg
;
825 aArg
.Mode
= OpenMode::DOCUMENT
;
826 aArg
.Priority
= 0; // unused
828 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
831 aCommand
.Name
= "open";
832 aCommand
.Handle
= -1; // n/a
833 aCommand
.Argument
<<= aArg
;
835 m_xImpl
->executeCommand( aCommand
);
841 bool Content::openStream( const Reference
< XOutputStream
>& rStream
)
842 throw( CommandAbortedException
, RuntimeException
, Exception
)
847 OpenCommandArgument2 aArg
;
848 aArg
.Mode
= OpenMode::DOCUMENT
;
849 aArg
.Priority
= 0; // unused
851 aArg
.Properties
= Sequence
< Property
>( 0 ); // unused
854 aCommand
.Name
= "open";
855 aCommand
.Handle
= -1; // n/a
856 aCommand
.Argument
<<= aArg
;
858 m_xImpl
->executeCommand( aCommand
);
864 void Content::writeStream( const Reference
< XInputStream
>& rStream
,
865 bool bReplaceExisting
)
866 throw( CommandAbortedException
, RuntimeException
, Exception
)
868 InsertCommandArgument aArg
;
869 aArg
.Data
= rStream
.is() ? rStream
: new EmptyInputStream
;
870 aArg
.ReplaceExisting
= bReplaceExisting
;
873 aCommand
.Name
= "insert";
874 aCommand
.Handle
= -1; // n/a
875 aCommand
.Argument
<<= aArg
;
877 m_xImpl
->executeCommand( aCommand
);
883 Sequence
< ContentInfo
> Content::queryCreatableContentsInfo()
884 throw( CommandAbortedException
, RuntimeException
, Exception
)
886 // First, try it using "CreatableContentsInfo" property -> the "new" way.
887 Sequence
< ContentInfo
> aInfo
;
888 if ( getPropertyValue(
889 OUString("CreatableContentsInfo") )
893 // Second, try it using XContentCreator interface -> the "old" way (not
894 // providing the chance to supply an XCommandEnvironment.
895 Reference
< XContentCreator
> xCreator( m_xImpl
->getContent(), UNO_QUERY
);
897 aInfo
= xCreator
->queryCreatableContentsInfo();
903 bool Content::insertNewContent( const OUString
& rContentType
,
904 const Sequence
< OUString
>&
906 const Sequence
< Any
>& rPropertyValues
,
907 Content
& rNewContent
)
908 throw( CommandAbortedException
, RuntimeException
, Exception
)
910 return insertNewContent( rContentType
,
913 new EmptyInputStream
,
918 bool Content::insertNewContent( const OUString
& rContentType
,
919 const Sequence
< OUString
>&
921 const Sequence
< Any
>& rPropertyValues
,
922 const Reference
< XInputStream
>& rData
,
923 Content
& rNewContent
)
924 throw( CommandAbortedException
, RuntimeException
, Exception
)
926 if ( rContentType
.isEmpty() )
929 // First, try it using "createNewContent" command -> the "new" way.
931 aInfo
.Type
= rContentType
;
932 aInfo
.Attributes
= 0;
935 aCommand
.Name
= "createNewContent";
936 aCommand
.Handle
= -1; // n/a
937 aCommand
.Argument
<<= aInfo
;
939 Reference
< XContent
> xNew
;
942 m_xImpl
->executeCommand( aCommand
) >>= xNew
;
944 catch ( RuntimeException
const & )
948 catch ( Exception
const & )
954 // Second, try it using XContentCreator interface -> the "old"
955 // way (not providing the chance to supply an XCommandEnvironment.
956 Reference
< XContentCreator
> xCreator( m_xImpl
->getContent(), UNO_QUERY
);
958 if ( !xCreator
.is() )
961 xNew
= xCreator
->createNewContent( aInfo
);
968 xNew
, m_xImpl
->getEnvironment(), m_xImpl
->getComponentContext() );
969 aNewContent
.setPropertyValues( rPropertyNames
, rPropertyValues
);
970 aNewContent
.executeCommand( OUString("insert"),
972 InsertCommandArgument(
973 rData
.is() ? rData
: new EmptyInputStream
,
974 sal_False
/* ReplaceExisting */ ) ) );
975 aNewContent
.m_xImpl
->inserted();
977 rNewContent
= aNewContent
;
982 bool Content::transferContent( const Content
& rSourceContent
,
983 InsertOperation eOperation
,
984 const OUString
& rTitle
,
985 const sal_Int32 nNameClashAction
,
986 const OUString
& rMimeType
,
988 const OUString
& rVersionComment
,
989 OUString
* pResultURL
,
990 const OUString
& rDocumentId
)
991 throw( CommandAbortedException
, RuntimeException
, Exception
)
993 Reference
< XUniversalContentBroker
> pBroker(
994 UniversalContentBroker::create( m_xImpl
->getComponentContext() ) );
996 // Execute command "globalTransfer" at UCB.
998 TransferCommandOperation eTransOp
= TransferCommandOperation();
999 OUString
sCommand( "globalTransfer" );
1000 bool bCheckIn
= false;
1001 switch ( eOperation
)
1003 case InsertOperation_COPY
:
1004 eTransOp
= TransferCommandOperation_COPY
;
1007 case InsertOperation_MOVE
:
1008 eTransOp
= TransferCommandOperation_MOVE
;
1011 case InsertOperation_LINK
:
1012 eTransOp
= TransferCommandOperation_LINK
;
1015 case InsertOperation_CHECKIN
:
1016 eTransOp
= TransferCommandOperation_COPY
;
1017 sCommand
= "checkin";
1022 aCommand
.Name
= sCommand
;
1023 aCommand
.Handle
= -1; // n/a
1027 GlobalTransferCommandArgument2
aTransferArg(
1029 rSourceContent
.getURL(), // SourceURL
1030 getURL(), // TargetFolderURL,
1035 aCommand
.Argument
<<= aTransferArg
;
1039 CheckinArgument
aCheckinArg( bMajorVersion
, rVersionComment
,
1040 rSourceContent
.getURL(), getURL(), rTitle
, rMimeType
);
1041 aCommand
.Argument
<<= aCheckinArg
;
1044 Any aRet
= pBroker
->execute( aCommand
, 0, m_xImpl
->getEnvironment() );
1045 if ( pResultURL
!= NULL
)
1046 aRet
>>= *pResultURL
;
1051 bool Content::isFolder()
1052 throw( CommandAbortedException
, RuntimeException
, Exception
)
1054 bool bFolder
= false;
1055 if ( getPropertyValue("IsFolder")
1059 ucbhelper::cancelCommandExecution(
1060 makeAny( UnknownPropertyException(
1062 "Unable to retrieve value of property 'IsFolder'!" ),
1064 m_xImpl
->getEnvironment() );
1066 #if !(defined(_MSC_VER) && defined(ENABLE_LTO))
1067 // Unreachable - cancelCommandExecution always throws an exception.
1068 // But some compilers complain...
1075 SAL_WNOUNREACHABLE_CODE_PUSH
1077 bool Content::isDocument()
1078 throw( CommandAbortedException
, RuntimeException
, Exception
)
1081 if ( getPropertyValue("IsDocument")
1085 ucbhelper::cancelCommandExecution(
1086 makeAny( UnknownPropertyException(
1088 "Unable to retrieve value of property 'IsDocument'!" ),
1090 m_xImpl
->getEnvironment() );
1092 // Unreachable - cancelCommandExecution always throws an exception,
1093 // But some compilers complain...
1097 SAL_WNOUNREACHABLE_CODE_POP
1102 // Content_Impl Implementation.
1107 Content_Impl::Content_Impl( const Reference
< XComponentContext
>& rCtx
,
1108 const Reference
< XContent
>& rContent
,
1109 const Reference
< XCommandEnvironment
>& rEnv
)
1111 m_xContent( rContent
),
1115 if ( m_xContent
.is() )
1117 m_xContentEventListener
= new ContentEventListener_Impl( *this );
1118 m_xContent
->addContentEventListener( m_xContentEventListener
);
1120 #if OSL_DEBUG_LEVEL > 1
1121 // Only done on demand in product version for performance reasons,
1122 // but a nice debug helper.
1129 void Content_Impl::reinit( const Reference
< XContent
>& xContent
)
1131 osl::MutexGuard
aGuard( m_aMutex
);
1133 m_xCommandProcessor
= 0;
1135 // #92581# - Don't reset m_aURL!!!
1137 if ( m_xContent
.is() )
1141 m_xContent
->removeContentEventListener( m_xContentEventListener
);
1143 catch ( RuntimeException
const & )
1148 if ( xContent
.is() )
1150 m_xContent
= xContent
;
1151 m_xContent
->addContentEventListener( m_xContentEventListener
);
1153 #if OSL_DEBUG_LEVEL > 1
1154 // Only done on demand in product version for performance reasons,
1155 // but a nice debug helper.
1161 // We need m_xContent's URL in order to be able to create the
1162 // content object again if demanded ( --> Content_Impl::getContent() )
1171 Content_Impl::~Content_Impl()
1173 if ( m_xContent
.is() )
1177 m_xContent
->removeContentEventListener( m_xContentEventListener
);
1179 catch ( RuntimeException
const & )
1186 void Content_Impl::disposing( const EventObject
& Source
)
1188 Reference
<XContent
> xContent
;
1191 osl::MutexGuard
aGuard( m_aMutex
);
1192 if(Source
.Source
!= m_xContent
)
1195 xContent
= m_xContent
;
1198 m_xCommandProcessor
= 0;
1202 if ( xContent
.is() )
1206 xContent
->removeContentEventListener( m_xContentEventListener
);
1208 catch ( RuntimeException
const & )
1215 const OUString
& Content_Impl::getURL() const
1217 if ( m_aURL
.isEmpty() && m_xContent
.is() )
1219 osl::MutexGuard
aGuard( m_aMutex
);
1221 if ( m_aURL
.isEmpty() && m_xContent
.is() )
1223 Reference
< XContentIdentifier
> xId
= m_xContent
->getIdentifier();
1225 m_aURL
= xId
->getContentIdentifier();
1233 Reference
< XContent
> Content_Impl::getContent()
1235 if ( !m_xContent
.is() && !m_aURL
.isEmpty() )
1237 osl::MutexGuard
aGuard( m_aMutex
);
1239 if ( !m_xContent
.is() && !m_aURL
.isEmpty() )
1241 Reference
< XUniversalContentBroker
> pBroker(
1242 UniversalContentBroker::create( getComponentContext() ) );
1244 OSL_ENSURE( pBroker
->queryContentProviders().getLength(),
1245 "Content Broker not configured (no providers)!" );
1247 Reference
< XContentIdentifier
> xId
1248 = pBroker
->createContentIdentifier( m_aURL
);
1250 OSL_ENSURE( xId
.is(), "No Content Identifier!" );
1256 m_xContent
= pBroker
->queryContent( xId
);
1258 catch ( IllegalIdentifierException
const & )
1262 if ( m_xContent
.is() )
1263 m_xContent
->addContentEventListener(
1264 m_xContentEventListener
);
1273 Reference
< XCommandProcessor
> Content_Impl::getCommandProcessor()
1275 if ( !m_xCommandProcessor
.is() )
1277 osl::MutexGuard
aGuard( m_aMutex
);
1279 if ( !m_xCommandProcessor
.is() )
1281 = Reference
< XCommandProcessor
>( getContent(), UNO_QUERY
);
1284 return m_xCommandProcessor
;
1288 Any
Content_Impl::executeCommand( const Command
& rCommand
)
1290 Reference
< XCommandProcessor
> xProc
= getCommandProcessor();
1295 return xProc
->execute( rCommand
, 0, m_xEnv
);
1299 inline const Reference
< XCommandEnvironment
>&
1300 Content_Impl::getEnvironment() const
1306 inline void Content_Impl::setEnvironment(
1307 const Reference
< XCommandEnvironment
>& xNewEnv
)
1309 osl::MutexGuard
aGuard( m_aMutex
);
1314 void Content_Impl::inserted()
1316 // URL might have changed during 'insert' => recalculate in next getURL()
1317 osl::MutexGuard
aGuard( m_aMutex
);
1324 // ContentEventListener_Impl Implementation.
1331 // XInterface methods.
1333 void SAL_CALL
ContentEventListener_Impl::acquire()
1336 OWeakObject::acquire();
1339 void SAL_CALL
ContentEventListener_Impl::release()
1342 OWeakObject::release();
1345 css::uno::Any SAL_CALL
ContentEventListener_Impl::queryInterface( const css::uno::Type
& rType
)
1346 throw( css::uno::RuntimeException
, std::exception
)
1348 css::uno::Any aRet
= cppu::queryInterface( rType
,
1349 (static_cast< XContentEventListener
* >(this)),
1350 (static_cast< XEventListener
* >(this))
1352 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
1355 // XContentEventListener methods.
1360 void SAL_CALL
ContentEventListener_Impl::contentEvent( const ContentEvent
& evt
)
1361 throw( RuntimeException
, std::exception
)
1363 if ( evt
.Source
== m_rContent
.m_xContent
)
1365 switch ( evt
.Action
)
1367 case ContentAction::DELETED
:
1368 m_rContent
.reinit( Reference
< XContent
>() );
1371 case ContentAction::EXCHANGED
:
1372 m_rContent
.reinit( evt
.Content
);
1383 // XEventListenr methods.
1388 void SAL_CALL
ContentEventListener_Impl::disposing( const EventObject
& Source
)
1389 throw( RuntimeException
, std::exception
)
1391 m_rContent
.disposing(Source
);
1394 } /* namespace ucbhelper */
1396 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */