1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ucblockbytes.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_unotools.hxx"
34 #include <unotools/ucblockbytes.hxx>
35 #include <comphelper/processfactory.hxx>
36 #include <salhelper/condition.hxx>
37 #ifndef _OSL_THREAD_HXX_
38 #include <osl/thread.hxx>
40 #include <tools/urlobj.hxx>
41 #include <ucbhelper/interactionrequest.hxx>
42 #include <com/sun/star/task/XInteractionAbort.hpp>
43 #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
44 #include <com/sun/star/ucb/CommandFailedException.hpp>
45 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
46 #ifndef _COM_SUN_STAR_UCB_INTERACTIVEIODEXCEPTION_HPP_
47 #include <com/sun/star/ucb/InteractiveIOException.hpp>
49 #include <com/sun/star/io/XActiveDataStreamer.hpp>
50 #include <com/sun/star/ucb/DocumentHeaderField.hpp>
51 #include <com/sun/star/ucb/XCommandInfo.hpp>
52 #include <com/sun/star/ucb/XCommandProcessor.hpp>
53 #include <com/sun/star/task/XInteractionHandler.hpp>
54 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
55 #include <com/sun/star/ucb/PostCommandArgument2.hpp>
56 #include <com/sun/star/ucb/OpenMode.hpp>
57 #include <com/sun/star/beans/Property.hpp>
58 #include <com/sun/star/beans/PropertyValue.hpp>
59 #include <com/sun/star/beans/XPropertiesChangeNotifier.hpp>
60 #include <com/sun/star/beans/XPropertiesChangeListener.hpp>
61 #include <com/sun/star/sdbc/XRow.hpp>
62 #include <com/sun/star/io/XActiveDataSink.hpp>
63 #include <com/sun/star/io/XActiveDataControl.hpp>
64 #include <com/sun/star/io/XSeekable.hpp>
65 #include <cppuhelper/implbase1.hxx>
66 #include <cppuhelper/implbase2.hxx>
67 #include <tools/inetmsg.hxx>
68 #include <com/sun/star/io/XTruncate.hpp>
69 #include <com/sun/star/lang/IllegalArgumentException.hpp>
71 #include <comphelper/storagehelper.hxx>
73 #include <ucbhelper/contentbroker.hxx>
74 #include <ucbhelper/content.hxx>
76 using namespace ::com::sun::star::uno
;
77 using namespace ::com::sun::star::io
;
78 using namespace ::com::sun::star::uno
;
79 using namespace ::com::sun::star::ucb
;
80 using namespace ::com::sun::star::task
;
81 using namespace ::com::sun::star::lang
;
82 using namespace ::com::sun::star::beans
;
89 Helper class for getting a XInputStream when opening a content
91 class UcbDataSink_Impl
: public ::cppu::WeakImplHelper2
< XActiveDataControl
, XActiveDataSink
>
93 UcbLockBytesRef m_xLockBytes
;
96 UcbDataSink_Impl( UcbLockBytes
* pLockBytes
)
97 : m_xLockBytes( pLockBytes
)
100 SvLockBytes
* getLockBytes (void)
101 { return m_xLockBytes
; }
103 // XActiveDataControl.
104 virtual void SAL_CALL
addListener ( const Reference
<XStreamListener
> &/*rxListener*/) throw(RuntimeException
) {}
105 virtual void SAL_CALL
removeListener ( const Reference
<XStreamListener
> &/*rxListener*/) throw(RuntimeException
) {}
106 virtual void SAL_CALL
start (void) throw(RuntimeException
) {}
107 virtual void SAL_CALL
terminate (void) throw(RuntimeException
)
108 { m_xLockBytes
->terminate_Impl(); }
111 virtual void SAL_CALL
setInputStream ( const Reference
<XInputStream
> &rxInputStream
) throw(RuntimeException
)
112 { m_xLockBytes
->setInputStream_Impl (rxInputStream
); }
113 virtual Reference
<XInputStream
> SAL_CALL
getInputStream (void) throw(RuntimeException
)
114 { return m_xLockBytes
->getInputStream_Impl(); }
118 Helper class for getting a XStream when opening a content
120 class UcbStreamer_Impl
: public ::cppu::WeakImplHelper2
< XActiveDataStreamer
, XActiveDataControl
>
122 Reference
< XStream
> m_xStream
;
123 UcbLockBytesRef m_xLockBytes
;
127 UcbStreamer_Impl( UcbLockBytes
* pLockBytes
)
128 : m_xLockBytes( pLockBytes
)
131 // XActiveDataControl.
132 virtual void SAL_CALL
addListener ( const Reference
<XStreamListener
> &/*rxListener*/) throw(RuntimeException
) {}
133 virtual void SAL_CALL
removeListener ( const Reference
<XStreamListener
> &/*rxListener*/) throw(RuntimeException
) {}
134 virtual void SAL_CALL
start (void) throw(RuntimeException
) {}
135 virtual void SAL_CALL
terminate (void) throw(RuntimeException
)
136 { m_xLockBytes
->terminate_Impl(); }
138 // XActiveDataStreamer
139 virtual void SAL_CALL
setStream( const Reference
< XStream
>& aStream
) throw(RuntimeException
)
140 { m_xStream
= aStream
; m_xLockBytes
->setStream_Impl( aStream
); }
141 virtual Reference
< XStream
> SAL_CALL
getStream() throw(RuntimeException
)
142 { return m_xStream
; }
146 Helper class for progress handling while executing UCB commands
148 class ProgressHandler_Impl
: public ::cppu::WeakImplHelper1
< XProgressHandler
>
153 ProgressHandler_Impl( const Link
& rLink
)
154 : m_aProgress( rLink
)
157 virtual void SAL_CALL
push(const Any
& /*rStatus*/) throw (RuntimeException
) {}
158 virtual void SAL_CALL
pop() throw (RuntimeException
) {}
159 virtual void SAL_CALL
update(const Any
& /*rStatus*/) throw (RuntimeException
)
160 { if ( m_aProgress
.IsSet() ) m_aProgress
.Call( 0 ); }
164 Helper class for managing interactions and progress when executing UCB commands
166 class UcbTaskEnvironment
: public ::cppu::WeakImplHelper1
< XCommandEnvironment
>
168 Reference
< XInteractionHandler
> m_xInteractionHandler
;
169 Reference
< XProgressHandler
> m_xProgressHandler
;
172 UcbTaskEnvironment( const Reference
< XInteractionHandler
>& rxInteractionHandler
,
173 const Reference
< XProgressHandler
>& rxProgressHandler
)
174 : m_xInteractionHandler( rxInteractionHandler
)
175 , m_xProgressHandler( rxProgressHandler
)
179 virtual Reference
<XInteractionHandler
> SAL_CALL
getInteractionHandler() throw (RuntimeException
)
180 { return m_xInteractionHandler
; }
182 virtual Reference
<XProgressHandler
> SAL_CALL
getProgressHandler() throw (RuntimeException
)
183 { return m_xProgressHandler
; }
188 Helper class for property change notifies when executing UCB commands
190 class UcbPropertiesChangeListener_Impl
: public ::cppu::WeakImplHelper1
< XPropertiesChangeListener
>
193 UcbLockBytesRef m_xLockBytes
;
195 UcbPropertiesChangeListener_Impl( UcbLockBytesRef rRef
)
196 : m_xLockBytes( rRef
)
199 virtual void SAL_CALL
disposing ( const EventObject
&/*rEvent*/) throw(RuntimeException
) {}
200 virtual void SAL_CALL
propertiesChange ( const Sequence
<PropertyChangeEvent
> &rEvent
) throw(RuntimeException
);
203 void SAL_CALL
UcbPropertiesChangeListener_Impl::propertiesChange ( const Sequence
<PropertyChangeEvent
> &rEvent
) throw(RuntimeException
)
205 sal_Int32 i
, n
= rEvent
.getLength();
206 for (i
= 0; i
< n
; i
++)
208 PropertyChangeEvent
evt (rEvent
[i
]);
209 if (evt
.PropertyName
== ::rtl::OUString::createFromAscii ("DocumentHeader"))
211 Sequence
<DocumentHeaderField
> aHead
;
212 if (evt
.NewValue
>>= aHead
)
214 sal_Int32 k
, m
= aHead
.getLength();
215 for (k
= 0; k
< m
; k
++)
217 String
aName( aHead
[k
].Name
);
218 String
aValue( aHead
[k
].Value
);
220 if (aName
.CompareIgnoreCaseToAscii("Expires") == COMPARE_EQUAL
)
222 DateTime
aExpires (0, 0);
223 if (INetRFC822Message::ParseDateField (aValue
, aExpires
))
225 aExpires
.ConvertToLocalTime();
226 m_xLockBytes
->SetExpireDate_Impl( aExpires
);
232 m_xLockBytes
->SetStreamValid_Impl();
234 else if (evt
.PropertyName
== rtl::OUString::createFromAscii ("PresentationURL"))
236 ::rtl::OUString aUrl
;
237 if (evt
.NewValue
>>= aUrl
)
239 ::rtl::OUString
aBad (::rtl::OUString::createFromAscii ("private:"));
240 if (!(aUrl
.compareTo (aBad
, aBad
.getLength()) == 0))
242 // URL changed (Redirection).
243 m_xLockBytes
->SetRealURL_Impl( aUrl
);
247 else if (evt
.PropertyName
== ::rtl::OUString::createFromAscii ("MediaType"))
249 ::rtl::OUString aContentType
;
250 if (evt
.NewValue
>>= aContentType
)
251 m_xLockBytes
->SetContentType_Impl( aContentType
);
261 // usage restriction:
262 // It might be possible, that the call to the interactionhandler and/or
263 // progresshandler is done asynchrounsly, while the 'execute' simply
264 // returns. This would imply that these class must be refcounted !!!
269 Reference
< XContent
>& xContent
,
270 Reference
< XInteractionHandler
>& xInteract
,
271 Reference
< XProgressHandler
>& xProgress
,
275 ContentCreationException
,
285 INTERACTIONREQUEST
, // reply expected
305 : public salhelper::Condition
309 ConditionRes(osl::Mutex
& aMutex
,Moderator
& aModerator
)
310 : salhelper::Condition(aMutex
),
311 m_aModerator(aModerator
)
317 bool applies() const {
318 return m_aModerator
.m_aResultType
!= NORESULT
;
323 Moderator
& m_aModerator
;
330 sal_Int32 ioErrorCode
;
334 Result
getResult(const sal_uInt32 milliSec
);
346 : public salhelper::Condition
350 ConditionRep(osl::Mutex
& aMutex
,Moderator
& aModerator
)
351 : salhelper::Condition(aMutex
),
352 m_aModerator(aModerator
)
358 bool applies() const {
359 return m_aModerator
.m_aReplyType
!= NOREPLY
;
364 Moderator
& m_aModerator
;
367 void setReply(ReplyType
);
370 void handle( const Reference
<XInteractionRequest
>& Request
);
372 void push( const Any
& Status
);
374 void update( const Any
& Status
);
378 void setStream(const Reference
< XStream
>& aStream
);
380 void setInputStream(const Reference
<XInputStream
> &rxInputStream
);
385 virtual void SAL_CALL
run();
387 virtual void SAL_CALL
onTerminated();
393 friend class ConditionRes
;
396 ResultType m_aResultType
;
397 sal_Int32 m_nIOErrorCode
;
400 friend class ConditionRep
;
403 ReplyType m_aReplyType
;
406 ::ucbhelper::Content m_aContent
;
410 class ModeratorsActiveDataStreamer
411 : public ::cppu::WeakImplHelper1
<XActiveDataStreamer
>
415 ModeratorsActiveDataStreamer(Moderator
&theModerator
);
417 ~ModeratorsActiveDataStreamer();
419 // XActiveDataStreamer
420 virtual void SAL_CALL
422 const Reference
< XStream
>& aStream
428 virtual Reference
<XStream
> SAL_CALL
435 osl::MutexGuard
aGuard(m_aMutex
);
442 Moderator
& m_aModerator
;
445 Reference
<XStream
> m_xStream
;
450 class ModeratorsActiveDataSink
451 : public ::cppu::WeakImplHelper1
<XActiveDataSink
>
455 ModeratorsActiveDataSink(Moderator
&theModerator
);
457 ~ModeratorsActiveDataSink();
460 virtual void SAL_CALL
462 const Reference
<XInputStream
> &rxInputStream
468 virtual Reference
<XInputStream
> SAL_CALL
475 osl::MutexGuard
aGuard(m_aMutex
);
482 Moderator
& m_aModerator
;
484 Reference
<XInputStream
> m_xStream
;
489 ModeratorsActiveDataSink::ModeratorsActiveDataSink(Moderator
&theModerator
)
490 : m_aModerator(theModerator
)
495 ModeratorsActiveDataSink::~ModeratorsActiveDataSink()
501 ModeratorsActiveDataSink::setInputStream (
502 const Reference
<XInputStream
> &rxInputStream
508 m_aModerator
.setInputStream(rxInputStream
);
509 osl::MutexGuard
aGuard(m_aMutex
);
510 m_xStream
= rxInputStream
;
514 ModeratorsActiveDataStreamer::ModeratorsActiveDataStreamer(
515 Moderator
&theModerator
517 : m_aModerator(theModerator
)
522 ModeratorsActiveDataStreamer::~ModeratorsActiveDataStreamer()
526 // XActiveDataStreamer.
528 ModeratorsActiveDataStreamer::setStream (
529 const Reference
<XStream
> &rxStream
535 m_aModerator
.setStream(rxStream
);
536 osl::MutexGuard
aGuard(m_aMutex
);
537 m_xStream
= rxStream
;
542 class ModeratorsInteractionHandler
543 : public ::cppu::WeakImplHelper1
<XInteractionHandler
>
547 ModeratorsInteractionHandler(Moderator
&theModerator
);
549 ~ModeratorsInteractionHandler();
551 virtual void SAL_CALL
552 handle( const Reference
<XInteractionRequest
>& Request
)
553 throw (RuntimeException
);
557 Moderator
& m_aModerator
;
561 class ModeratorsProgressHandler
562 : public ::cppu::WeakImplHelper1
<XProgressHandler
>
566 ModeratorsProgressHandler(Moderator
&theModerator
);
568 ~ModeratorsProgressHandler();
570 virtual void SAL_CALL
push( const Any
& Status
)
574 virtual void SAL_CALL
update( const Any
& Status
)
575 throw (RuntimeException
);
577 virtual void SAL_CALL
pop( )
578 throw (RuntimeException
);
583 Moderator
& m_aModerator
;
587 ModeratorsProgressHandler::ModeratorsProgressHandler(Moderator
&theModerator
)
588 : m_aModerator(theModerator
)
592 ModeratorsProgressHandler::~ModeratorsProgressHandler()
597 void SAL_CALL
ModeratorsProgressHandler::push( const Any
& Status
)
601 m_aModerator
.push(Status
);
605 void SAL_CALL
ModeratorsProgressHandler::update( const Any
& Status
)
606 throw (RuntimeException
)
608 m_aModerator
.update(Status
);
612 void SAL_CALL
ModeratorsProgressHandler::pop( )
613 throw (RuntimeException
)
621 ModeratorsInteractionHandler::ModeratorsInteractionHandler(
622 Moderator
&aModerator
)
623 : m_aModerator(aModerator
)
628 ModeratorsInteractionHandler::~ModeratorsInteractionHandler()
634 ModeratorsInteractionHandler::handle(
635 const Reference
<XInteractionRequest
>& Request
641 // wakes up the mainthread
642 m_aModerator
.handle(Request
);
648 Moderator::Moderator(
649 Reference
< XContent
>& xContent
,
650 Reference
< XInteractionHandler
>& xInteract
,
651 Reference
< XProgressHandler
>& xProgress
,
655 ::com::sun::star::ucb::ContentCreationException
,
656 ::com::sun::star::uno::RuntimeException
660 m_aRes(m_aMutex
,*this),
661 m_aResultType(NORESULT
),
665 m_aRep(m_aMutex
,*this),
666 m_aReplyType(NOREPLY
),
671 new UcbTaskEnvironment(
672 xInteract
.is() ? new ModeratorsInteractionHandler(*this) : 0,
673 xProgress
.is() ? new ModeratorsProgressHandler(*this) : 0
676 // now exchange the whole data sink stuff
677 // with a thread safe version
679 Reference
<XInterface
> *pxSink
= NULL
;
681 PostCommandArgument2 aPostArg
;
682 OpenCommandArgument2 aOpenArg
;
685 if(m_aArg
.Argument
>>= aPostArg
) {
686 pxSink
= &aPostArg
.Sink
;
689 else if(m_aArg
.Argument
>>= aOpenArg
) {
690 pxSink
= &aOpenArg
.Sink
;
695 throw ContentCreationException();
697 Reference
< XActiveDataSink
> xActiveSink(*pxSink
,UNO_QUERY
);
699 *pxSink
= Reference
<XInterface
>(
700 (cppu::OWeakObject
*)new ModeratorsActiveDataSink(*this));
702 Reference
<XActiveDataStreamer
> xStreamer( *pxSink
, UNO_QUERY
);
703 if ( xStreamer
.is() )
704 *pxSink
= Reference
<XInterface
>(
705 (cppu::OWeakObject
*)new ModeratorsActiveDataStreamer(*this));
708 m_aArg
.Argument
<<= aPostArg
;
710 m_aArg
.Argument
<<= aOpenArg
;
714 Moderator::~Moderator()
719 Moderator::Result
Moderator::getResult(const sal_uInt32 milliSec
)
723 salhelper::ConditionWaiter
aWaiter(m_aRes
,milliSec
);
724 ret
.type
= m_aResultType
;
725 ret
.result
= m_aResult
;
726 ret
.ioErrorCode
= m_nIOErrorCode
;
729 m_aResultType
= NORESULT
;
731 catch(const salhelper::ConditionWaiter::timedout
&)
740 void Moderator::setReply(ReplyType aReplyType
)
742 salhelper::ConditionModifier
aMod(m_aRep
);
743 m_aReplyType
= aReplyType
;
747 void Moderator::handle( const Reference
<XInteractionRequest
>& Request
)
749 ReplyType aReplyType
;
753 salhelper::ConditionModifier
aMod(m_aRes
);
754 m_aResultType
= INTERACTIONREQUEST
;
755 m_aResult
<<= Request
;
759 salhelper::ConditionWaiter
aWait(m_aRep
);
760 aReplyType
= m_aReplyType
;
763 m_aReplyType
= NOREPLY
;
766 if(aReplyType
== EXIT
) {
767 Sequence
<Reference
<XInteractionContinuation
> > aSeq(
768 Request
->getContinuations());
769 for(sal_Int32 i
= 0; i
< aSeq
.getLength(); ++i
) {
770 Reference
<XInteractionAbort
> aRef(aSeq
[i
],UNO_QUERY
);
776 // resignal the exitcondition
780 } while(aReplyType
!= REQUESTHANDLED
);
785 void Moderator::push( const Any
& Status
)
788 salhelper::ConditionModifier
aMod(m_aRes
);
789 m_aResultType
= PROGRESSPUSH
;
792 ReplyType aReplyType
;
794 salhelper::ConditionWaiter
aWait(m_aRep
);
795 aReplyType
= m_aReplyType
;
796 m_aReplyType
= NOREPLY
;
798 if(aReplyType
== EXIT
)
803 void Moderator::update( const Any
& Status
)
806 salhelper::ConditionModifier
aMod(m_aRes
);
807 m_aResultType
= PROGRESSUPDATE
;
810 ReplyType aReplyType
;
812 salhelper::ConditionWaiter
aWait(m_aRep
);
813 aReplyType
= m_aReplyType
;
814 m_aReplyType
= NOREPLY
;
816 if(aReplyType
== EXIT
)
821 void Moderator::pop( )
824 salhelper::ConditionModifier
aMod(m_aRes
);
825 m_aResultType
= PROGRESSPOP
;
827 ReplyType aReplyType
;
829 salhelper::ConditionWaiter
aWait(m_aRep
);
830 aReplyType
= m_aReplyType
;
831 m_aReplyType
= NOREPLY
;
833 if(aReplyType
== EXIT
)
838 void Moderator::setStream(const Reference
< XStream
>& aStream
)
841 salhelper::ConditionModifier
aMod(m_aRes
);
842 m_aResultType
= STREAM
;
843 m_aResult
<<= aStream
;
845 ReplyType aReplyType
;
847 salhelper::ConditionWaiter
aWait(m_aRep
);
848 aReplyType
= m_aReplyType
;
849 m_aReplyType
= NOREPLY
;
851 if(aReplyType
== EXIT
)
856 void Moderator::setInputStream(const Reference
<XInputStream
> &rxInputStream
)
859 salhelper::ConditionModifier
aMod(m_aRes
);
860 m_aResultType
= INPUTSTREAM
;
861 m_aResult
<<= rxInputStream
;
863 ReplyType aReplyType
;
865 salhelper::ConditionWaiter
aWait(m_aRep
);
866 aReplyType
= m_aReplyType
;
867 m_aReplyType
= NOREPLY
;
869 if(aReplyType
== EXIT
)
875 void SAL_CALL
Moderator::run()
877 ResultType aResultType
;
879 sal_Int32 nIOErrorCode
= 0;
883 aResult
= m_aContent
.executeCommand(m_aArg
.Name
,m_aArg
.Argument
);
884 aResultType
= RESULT
;
886 catch ( CommandAbortedException
)
888 aResultType
= COMMANDABORTED
;
890 catch ( CommandFailedException
)
892 aResultType
= COMMANDFAILED
;
894 catch ( InteractiveIOException
& r
)
896 nIOErrorCode
= r
.Code
;
897 aResultType
= INTERACTIVEIO
;
899 catch ( UnsupportedDataSinkException
& )
901 aResultType
= UNSUPPORTED
;
905 aResultType
= GENERAL
;
909 salhelper::ConditionModifier
aMod(m_aRes
);
910 m_aResultType
= aResultType
;
912 m_nIOErrorCode
= nIOErrorCode
;
918 void SAL_CALL
Moderator::onTerminated()
921 salhelper::ConditionWaiter
aWaiter(m_aRep
);
928 Function for opening UCB contents synchronously,
929 but with handled timeout;
932 static sal_Bool
_UCBOpenContentSync(
933 UcbLockBytesRef xLockBytes
,
934 Reference
< XContent
> xContent
,
936 Reference
< XInterface
> xSink
,
937 Reference
< XInteractionHandler
> xInteract
,
938 Reference
< XProgressHandler
> xProgress
,
939 UcbLockBytesHandlerRef xHandler
);
942 static sal_Bool
UCBOpenContentSync(
943 UcbLockBytesRef xLockBytes
,
944 Reference
< XContent
> xContent
,
946 Reference
< XInterface
> xSink
,
947 Reference
< XInteractionHandler
> xInteract
,
948 Reference
< XProgressHandler
> xProgress
,
949 UcbLockBytesHandlerRef xHandler
)
951 // http protocol must be handled in a special way:
952 // during the opening process the input stream may change
953 // only the last inputstream after notifying the document
956 Reference
<XContentIdentifier
> xContId(
957 xContent
.is() ? xContent
->getIdentifier() : 0 );
959 rtl::OUString aScheme
;
961 aScheme
= xContId
->getContentProviderScheme();
963 // now determine wether we use a timeout or not;
964 if( ! aScheme
.equalsIgnoreAsciiCaseAscii("http") &&
965 ! aScheme
.equalsIgnoreAsciiCaseAscii("https") &&
966 ! aScheme
.equalsIgnoreAsciiCaseAscii("vnd.sun.star.webdav") &&
967 ! aScheme
.equalsIgnoreAsciiCaseAscii("dav") &&
968 ! aScheme
.equalsIgnoreAsciiCaseAscii("davs") &&
969 ! aScheme
.equalsIgnoreAsciiCaseAscii("webdav") &&
970 ! aScheme
.equalsIgnoreAsciiCaseAscii("webdavs") &&
971 ! aScheme
.equalsIgnoreAsciiCaseAscii("ftp"))
972 return _UCBOpenContentSync(
973 xLockBytes
,xContent
,rArg
,xSink
,xInteract
,xProgress
,xHandler
);
975 if ( (aScheme
.compareToAscii( "http" ) != COMPARE_EQUAL
) ||
976 (aScheme
.compareToAscii( "https" ) != COMPARE_EQUAL
) )
977 xLockBytes
->SetStreamValid_Impl();
979 Reference
< XPropertiesChangeListener
> xListener
;
980 Reference
< XPropertiesChangeNotifier
> xProps(xContent
,UNO_QUERY
);
983 new UcbPropertiesChangeListener_Impl(xLockBytes
);
984 xProps
->addPropertiesChangeListener(
985 Sequence
< ::rtl::OUString
>(),
990 bool bException(false);
991 bool bAborted(false);
992 bool bResultAchieved(false);
996 pMod
= new Moderator(xContent
,xInteract
,xProgress
,rArg
);
998 } catch(const ContentCreationException
&) {
999 bResultAchieved
= bException
= true;
1000 xLockBytes
->SetError( ERRCODE_IO_GENERAL
);
1003 sal_uInt32
nTimeout(5000); // initially 5000 milliSec
1004 while(!bResultAchieved
) {
1006 Moderator::Result res
;
1007 // try to get the result for with timeout
1008 res
= pMod
->getResult(nTimeout
);
1011 case Moderator::PROGRESSPUSH
:
1014 xProgress
->push(res
.result
);
1015 pMod
->setReply(Moderator::REQUESTHANDLED
);
1018 case Moderator::PROGRESSUPDATE
:
1021 xProgress
->update(res
.result
);
1022 pMod
->setReply(Moderator::REQUESTHANDLED
);
1025 case Moderator::PROGRESSPOP
:
1029 pMod
->setReply(Moderator::REQUESTHANDLED
);
1032 case Moderator::STREAM
:
1034 Reference
<XStream
> result
;
1035 if(res
.result
>>= result
) {
1036 Reference
< XActiveDataStreamer
> xStreamer(
1041 xStreamer
->setStream(result
);
1043 pMod
->setReply(Moderator::REQUESTHANDLED
);
1046 case Moderator::INPUTSTREAM
:
1048 Reference
<XInputStream
> result
;
1049 res
.result
>>= result
;
1050 Reference
< XActiveDataSink
> xActiveSink(
1054 if(xActiveSink
.is())
1055 xActiveSink
->setInputStream(result
);
1056 pMod
->setReply(Moderator::REQUESTHANDLED
);
1059 case Moderator::TIMEDOUT
:
1061 Reference
<XInteractionRetry
> xRet
;
1062 if(xInteract
.is()) {
1063 InteractiveNetworkConnectException aExcep
;
1066 xContId
->getContentIdentifier() :
1068 aExcep
.Server
= aURL
.GetHost();
1069 aExcep
.Classification
= InteractionClassification_ERROR
;
1072 RTL_CONSTASCII_USTRINGPARAM(
1073 "server not responding after five seconds"));
1076 ucbhelper::InteractionRequest
*ir
=
1077 new ucbhelper::InteractionRequest(request
);
1078 Reference
<XInteractionRequest
> xIR(ir
);
1079 Sequence
<Reference
<XInteractionContinuation
> > aSeq(2);
1080 ucbhelper::InteractionRetry
*retryP
=
1081 new ucbhelper::InteractionRetry(ir
);
1083 ucbhelper::InteractionAbort
*abortP
=
1084 new ucbhelper::InteractionAbort(ir
);
1087 ir
->setContinuations(aSeq
);
1088 xInteract
->handle(xIR
);
1089 rtl::Reference
< ucbhelper::InteractionContinuation
> ref
1090 = ir
->getSelection();
1092 Reference
<XInterface
> xInt(ref
.get());
1093 xRet
= Reference
<XInteractionRetry
>(xInt
,UNO_QUERY
);
1099 xLockBytes
->SetError(ERRCODE_ABORT
);
1104 case Moderator::INTERACTIONREQUEST
:
1106 Reference
<XInteractionRequest
> Request
;
1107 res
.result
>>= Request
;
1108 xInteract
->handle(Request
);
1109 pMod
->setReply(Moderator::REQUESTHANDLED
);
1112 case Moderator::RESULT
:
1114 bResultAchieved
= true;
1115 aResult
= res
.result
;
1118 case Moderator::COMMANDABORTED
:
1121 xLockBytes
->SetError( ERRCODE_ABORT
);
1124 case Moderator::COMMANDFAILED
:
1127 xLockBytes
->SetError( ERRCODE_ABORT
);
1130 case Moderator::INTERACTIVEIO
:
1133 if ( res
.ioErrorCode
== IOErrorCode_ACCESS_DENIED
||
1134 res
.ioErrorCode
== IOErrorCode_LOCKING_VIOLATION
)
1135 xLockBytes
->SetError( ERRCODE_IO_ACCESSDENIED
);
1136 else if ( res
.ioErrorCode
== IOErrorCode_NOT_EXISTING
)
1137 xLockBytes
->SetError( ERRCODE_IO_NOTEXISTS
);
1138 else if ( res
.ioErrorCode
== IOErrorCode_CANT_READ
)
1139 xLockBytes
->SetError( ERRCODE_IO_CANTREAD
);
1141 xLockBytes
->SetError( ERRCODE_IO_GENERAL
);
1144 case Moderator::UNSUPPORTED
:
1147 xLockBytes
->SetError( ERRCODE_IO_NOTSUPPORTED
);
1153 xLockBytes
->SetError( ERRCODE_IO_GENERAL
);
1158 bResultAchieved
|= bException
;
1159 bResultAchieved
|= bAborted
;
1160 if(nTimeout
== 5000) nTimeout
*= 2;
1163 if(pMod
) pMod
->setReply(Moderator::EXIT
);
1165 if ( bAborted
|| bException
)
1168 xHandler
->Handle( UcbLockBytesHandler::CANCEL
, xLockBytes
);
1170 Reference
< XActiveDataSink
> xActiveSink( xSink
, UNO_QUERY
);
1171 if ( xActiveSink
.is() )
1172 xActiveSink
->setInputStream( Reference
< XInputStream
>() );
1174 Reference
< XActiveDataStreamer
> xStreamer( xSink
, UNO_QUERY
);
1175 if ( xStreamer
.is() )
1176 xStreamer
->setStream( Reference
< XStream
>() );
1179 Reference
< XActiveDataControl
> xControl( xSink
, UNO_QUERY
);
1180 if ( xControl
.is() )
1181 xControl
->terminate();
1184 xProps
->removePropertiesChangeListener(
1185 Sequence
< ::rtl::OUString
>(),
1188 return ( bAborted
|| bException
);
1192 Function for opening UCB contents synchronously
1194 static sal_Bool
_UCBOpenContentSync(
1195 UcbLockBytesRef xLockBytes
,
1196 Reference
< XContent
> xContent
,
1197 const Command
& rArg
,
1198 Reference
< XInterface
> xSink
,
1199 Reference
< XInteractionHandler
> xInteract
,
1200 Reference
< XProgressHandler
> xProgress
,
1201 UcbLockBytesHandlerRef xHandler
)
1203 ::ucbhelper::Content
aContent( xContent
, new UcbTaskEnvironment( xInteract
, xProgress
) );
1204 Reference
< XContentIdentifier
> xIdent
= xContent
->getIdentifier();
1205 ::rtl::OUString aScheme
= xIdent
->getContentProviderScheme();
1207 // http protocol must be handled in a special way: during the opening process the input stream may change
1208 // only the last inputstream after notifying the document headers is valid
1209 if ( aScheme
.compareToAscii("http") != COMPARE_EQUAL
)
1210 xLockBytes
->SetStreamValid_Impl();
1212 Reference
< XPropertiesChangeListener
> xListener
= new UcbPropertiesChangeListener_Impl( xLockBytes
);
1213 Reference
< XPropertiesChangeNotifier
> xProps ( xContent
, UNO_QUERY
);
1215 xProps
->addPropertiesChangeListener( Sequence
< ::rtl::OUString
>(), xListener
);
1218 bool bException
= false;
1219 bool bAborted
= false;
1223 aResult
= aContent
.executeCommand( rArg
.Name
, rArg
.Argument
);
1225 catch ( CommandAbortedException
)
1228 xLockBytes
->SetError( ERRCODE_ABORT
);
1230 catch ( CommandFailedException
)
1233 xLockBytes
->SetError( ERRCODE_ABORT
);
1235 catch ( InteractiveIOException
& r
)
1238 if ( r
.Code
== IOErrorCode_ACCESS_DENIED
|| r
.Code
== IOErrorCode_LOCKING_VIOLATION
)
1239 xLockBytes
->SetError( ERRCODE_IO_ACCESSDENIED
);
1240 else if ( r
.Code
== IOErrorCode_NOT_EXISTING
)
1241 xLockBytes
->SetError( ERRCODE_IO_NOTEXISTS
);
1242 else if ( r
.Code
== IOErrorCode_CANT_READ
)
1243 xLockBytes
->SetError( ERRCODE_IO_CANTREAD
);
1245 xLockBytes
->SetError( ERRCODE_IO_GENERAL
);
1247 catch ( UnsupportedDataSinkException
& )
1250 xLockBytes
->SetError( ERRCODE_IO_NOTSUPPORTED
);
1255 xLockBytes
->SetError( ERRCODE_IO_GENERAL
);
1258 if ( bAborted
|| bException
)
1261 xHandler
->Handle( UcbLockBytesHandler::CANCEL
, xLockBytes
);
1263 Reference
< XActiveDataSink
> xActiveSink( xSink
, UNO_QUERY
);
1264 if ( xActiveSink
.is() )
1265 xActiveSink
->setInputStream( Reference
< XInputStream
>() );
1267 Reference
< XActiveDataStreamer
> xStreamer( xSink
, UNO_QUERY
);
1268 if ( xStreamer
.is() )
1269 xStreamer
->setStream( Reference
< XStream
>() );
1272 Reference
< XActiveDataControl
> xControl( xSink
, UNO_QUERY
);
1273 if ( xControl
.is() )
1274 xControl
->terminate();
1278 xProps
->removePropertiesChangeListener( Sequence
< ::rtl::OUString
>(), xListener
);
1280 return ( bAborted
|| bException
);
1284 //----------------------------------------------------------------------------
1285 UcbLockBytes::UcbLockBytes( UcbLockBytesHandler
* pHandler
)
1286 : m_xInputStream (NULL
)
1287 , m_pCommandThread( NULL
)
1288 , m_xHandler( pHandler
)
1289 , m_nError( ERRCODE_NONE
)
1290 , m_bTerminated (sal_False
)
1291 , m_bDontClose( sal_False
)
1292 , m_bStreamValid (sal_False
)
1294 SetSynchronMode( TRUE
);
1297 //----------------------------------------------------------------------------
1298 UcbLockBytes::~UcbLockBytes()
1300 if ( !m_bDontClose
)
1302 if ( m_xInputStream
.is() )
1306 m_xInputStream
->closeInput();
1308 catch ( RuntimeException
const & )
1310 catch ( IOException
const & )
1315 if ( !m_xInputStream
.is() && m_xOutputStream
.is() )
1319 m_xOutputStream
->closeOutput();
1321 catch ( RuntimeException
const & )
1323 catch ( IOException
const & )
1328 Reference
< XInputStream
> UcbLockBytes::getInputStream()
1330 vos::OClearableGuard
aGuard( m_aMutex
);
1331 m_bDontClose
= sal_True
;
1332 return m_xInputStream
;
1335 Reference
< XStream
> UcbLockBytes::getStream()
1337 vos::OClearableGuard
aGuard( m_aMutex
);
1338 Reference
< XStream
> xStream( m_xSeekable
, UNO_QUERY
);
1340 m_bDontClose
= sal_True
;
1344 //----------------------------------------------------------------------------
1346 sal_Bool
UcbLockBytes::setStream_Impl( const Reference
<XStream
>& aStream
)
1348 vos::OClearableGuard
aGuard( m_aMutex
);
1351 m_xOutputStream
= aStream
->getOutputStream();
1352 setInputStream_Impl( aStream
->getInputStream(), sal_False
);
1353 m_xSeekable
= Reference
< XSeekable
> ( aStream
, UNO_QUERY
);
1357 m_xOutputStream
= Reference
< XOutputStream
>();
1358 setInputStream_Impl( Reference
< XInputStream
>() );
1361 return m_xInputStream
.is();
1364 sal_Bool
UcbLockBytes::setInputStream_Impl( const Reference
<XInputStream
> &rxInputStream
, sal_Bool bSetXSeekable
)
1366 sal_Bool bRet
= sal_False
;
1370 vos::OClearableGuard
aGuard( m_aMutex
);
1372 if ( !m_bDontClose
&& m_xInputStream
.is() )
1373 m_xInputStream
->closeInput();
1375 m_xInputStream
= rxInputStream
;
1379 m_xSeekable
= Reference
< XSeekable
> ( rxInputStream
, UNO_QUERY
);
1380 if( !m_xSeekable
.is() && rxInputStream
.is() )
1382 Reference
< XMultiServiceFactory
> xFactory
= ::comphelper::getProcessServiceFactory();
1383 Reference
< XOutputStream
> rxTempOut
= Reference
< XOutputStream
> (
1384 xFactory
->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
1387 if( rxTempOut
.is() )
1389 ::comphelper::OStorageHelper::CopyInputToOutput( rxInputStream
, rxTempOut
);
1390 m_xInputStream
= Reference
< XInputStream
>( rxTempOut
, UNO_QUERY
);
1391 m_xSeekable
= Reference
< XSeekable
> ( rxTempOut
, UNO_QUERY
);
1396 bRet
= m_xInputStream
.is();
1402 if ( m_bStreamValid
&& m_xInputStream
.is() )
1403 m_aInitialized
.set();
1408 void UcbLockBytes::SetStreamValid_Impl()
1410 m_bStreamValid
= sal_True
;
1411 if ( m_xInputStream
.is() )
1412 m_aInitialized
.set();
1415 //----------------------------------------------------------------------------
1416 void UcbLockBytes::terminate_Impl()
1418 m_bTerminated
= sal_True
;
1419 m_aInitialized
.set();
1420 m_aTerminated
.set();
1422 if ( GetError() == ERRCODE_NONE
&& !m_xInputStream
.is() )
1424 DBG_ERROR("No InputStream, but no error set!" );
1425 SetError( ERRCODE_IO_NOTEXISTS
);
1428 if ( m_xHandler
.Is() )
1429 m_xHandler
->Handle( UcbLockBytesHandler::DONE
, this );
1432 //----------------------------------------------------------------------------
1433 void UcbLockBytes::SetSynchronMode (BOOL bSynchron
)
1435 SvLockBytes::SetSynchronMode (bSynchron
);
1438 //----------------------------------------------------------------------------
1439 ErrCode
UcbLockBytes::ReadAt ( ULONG nPos
, void *pBuffer
, ULONG nCount
, ULONG
*pRead
) const
1441 if ( IsSynchronMode() )
1443 UcbLockBytes
* pThis
= const_cast < UcbLockBytes
* >( this );
1444 pThis
->m_aInitialized
.wait();
1447 Reference
<XInputStream
> xStream
= getInputStream_Impl();
1448 if ( !xStream
.is() )
1450 if ( m_bTerminated
)
1451 return ERRCODE_IO_CANTREAD
;
1453 return ERRCODE_IO_PENDING
;
1459 Reference
<XSeekable
> xSeekable
= getSeekable_Impl();
1460 if ( !xSeekable
.is() )
1461 return ERRCODE_IO_CANTREAD
;
1465 xSeekable
->seek( nPos
);
1467 catch ( IOException
)
1469 return ERRCODE_IO_CANTSEEK
;
1471 catch (com::sun::star::lang::IllegalArgumentException
)
1473 return ERRCODE_IO_CANTSEEK
;
1476 Sequence
<sal_Int8
> aData
;
1479 nCount
= VOS_MIN(nCount
, 0x7FFFFFFF);
1482 if ( !m_bTerminated
&& !IsSynchronMode() )
1484 sal_uInt64 nLen
= xSeekable
->getLength();
1485 if ( nPos
+ nCount
> nLen
)
1486 return ERRCODE_IO_PENDING
;
1489 nSize
= xStream
->readBytes( aData
, sal_Int32(nCount
) );
1493 return ERRCODE_IO_CANTREAD
;
1496 rtl_copyMemory (pBuffer
, aData
.getConstArray(), nSize
);
1498 *pRead
= ULONG(nSize
);
1500 return ERRCODE_NONE
;
1503 //----------------------------------------------------------------------------
1504 ErrCode
UcbLockBytes::WriteAt ( ULONG nPos
, const void *pBuffer
, ULONG nCount
, ULONG
*pWritten
)
1509 DBG_ASSERT( IsSynchronMode(), "Writing is only possible in SynchronMode!" );
1510 DBG_ASSERT( m_aInitialized
.check(), "Writing bevor stream is ready!" );
1512 Reference
<XSeekable
> xSeekable
= getSeekable_Impl();
1513 Reference
<XOutputStream
> xOutputStream
= getOutputStream_Impl();
1514 if ( !xOutputStream
.is() || !xSeekable
.is() )
1515 return ERRCODE_IO_CANTWRITE
;
1519 xSeekable
->seek( nPos
);
1521 catch ( IOException
)
1523 return ERRCODE_IO_CANTSEEK
;
1526 sal_Int8
* pData
= (sal_Int8
*) pBuffer
;
1527 Sequence
<sal_Int8
> aData( pData
, nCount
);
1530 xOutputStream
->writeBytes( aData
);
1536 return ERRCODE_IO_CANTWRITE
;
1539 return ERRCODE_NONE
;
1542 //----------------------------------------------------------------------------
1543 ErrCode
UcbLockBytes::Flush() const
1545 Reference
<XOutputStream
> xOutputStream
= getOutputStream_Impl();
1546 if ( !xOutputStream
.is() )
1547 return ERRCODE_IO_CANTWRITE
;
1549 xOutputStream
->flush();
1553 return ERRCODE_IO_CANTWRITE
;
1555 return ERRCODE_NONE
;
1558 //----------------------------------------------------------------------------
1559 ErrCode
UcbLockBytes::SetSize (ULONG nNewSize
)
1561 SvLockBytesStat aStat
;
1562 Stat( &aStat
, (SvLockBytesStatFlag
) 0 );
1563 ULONG nSize
= aStat
.nSize
;
1565 if ( nSize
> nNewSize
)
1567 Reference
< XTruncate
> xTrunc( getOutputStream_Impl(), UNO_QUERY
);
1574 DBG_WARNING("Not truncatable!");
1578 if ( nSize
< nNewSize
)
1580 ULONG nDiff
= nNewSize
-nSize
, nCount
=0;
1581 BYTE
* pBuffer
= new BYTE
[ nDiff
];
1582 memset(pBuffer
, 0, nDiff
); // initialize for enhanced security
1583 WriteAt( nSize
, pBuffer
, nDiff
, &nCount
);
1585 if ( nCount
!= nDiff
)
1586 return ERRCODE_IO_CANTWRITE
;
1589 return ERRCODE_NONE
;
1592 //----------------------------------------------------------------------------
1593 ErrCode
UcbLockBytes::Stat( SvLockBytesStat
*pStat
, SvLockBytesStatFlag
) const
1595 if ( IsSynchronMode() )
1597 UcbLockBytes
* pThis
= const_cast < UcbLockBytes
* >( this );
1598 pThis
->m_aInitialized
.wait();
1602 return ERRCODE_IO_INVALIDPARAMETER
;
1604 Reference
<XInputStream
> xStream
= getInputStream_Impl();
1605 Reference
<XSeekable
> xSeekable
= getSeekable_Impl();
1607 if ( !xStream
.is() )
1609 if ( m_bTerminated
)
1610 return ERRCODE_IO_INVALIDACCESS
;
1612 return ERRCODE_IO_PENDING
;
1614 else if( !xSeekable
.is() )
1615 return ERRCODE_IO_CANTTELL
;
1619 pStat
->nSize
= ULONG(xSeekable
->getLength());
1623 return ERRCODE_IO_CANTTELL
;
1626 return ERRCODE_NONE
;
1629 //----------------------------------------------------------------------------
1630 void UcbLockBytes::Cancel()
1632 // is alive only for compatibility reasons
1633 OSL_ENSURE( m_bTerminated
, "UcbLockBytes is not thread safe so it can be used only syncronously!\n" );
1636 //----------------------------------------------------------------------------
1637 IMPL_LINK( UcbLockBytes
, DataAvailHdl
, void*, EMPTYARG
)
1639 if ( hasInputStream_Impl() && m_xHandler
.Is() )
1640 m_xHandler
->Handle( UcbLockBytesHandler::DATA_AVAILABLE
, this );
1645 UcbLockBytesRef
UcbLockBytes::CreateInputLockBytes( const Reference
< XInputStream
>& xInputStream
)
1647 if( !xInputStream
.is() )
1650 UcbLockBytesRef xLockBytes
= new UcbLockBytes();
1651 xLockBytes
->setDontClose_Impl();
1652 xLockBytes
->setInputStream_Impl( xInputStream
);
1653 xLockBytes
->terminate_Impl();
1657 UcbLockBytesRef
UcbLockBytes::CreateLockBytes( const Reference
< XStream
>& xStream
)
1662 UcbLockBytesRef xLockBytes
= new UcbLockBytes();
1663 xLockBytes
->setDontClose_Impl();
1664 xLockBytes
->setStream_Impl( xStream
);
1665 xLockBytes
->terminate_Impl();
1669 UcbLockBytesRef
UcbLockBytes::CreateLockBytes( const Reference
< XContent
>& xContent
, const ::rtl::OUString
& rReferer
, const ::rtl::OUString
& rMediaType
,
1670 const Reference
< XInputStream
>& xPostData
, const Reference
< XInteractionHandler
>& xInteractionHandler
, UcbLockBytesHandler
* pHandler
)
1672 if( !xContent
.is() )
1675 UcbLockBytesRef xLockBytes
= new UcbLockBytes( pHandler
);
1676 xLockBytes
->SetSynchronMode( !pHandler
);
1677 Reference
< XActiveDataControl
> xSink
= (XActiveDataControl
*) new UcbDataSink_Impl( xLockBytes
);
1679 PostCommandArgument2 aArgument
;
1680 aArgument
.Source
= xPostData
;
1681 aArgument
.Sink
= xSink
;
1682 aArgument
.MediaType
= rMediaType
;
1683 aArgument
.Referer
= rReferer
;
1686 aCommand
.Name
= ::rtl::OUString::createFromAscii ("post");
1687 aCommand
.Argument
<<= aArgument
;
1689 Reference
< XProgressHandler
> xProgressHdl
= new ProgressHandler_Impl( LINK( &xLockBytes
, UcbLockBytes
, DataAvailHdl
) );
1691 sal_Bool bError
= UCBOpenContentSync( xLockBytes
,
1695 xInteractionHandler
,
1699 if ( xLockBytes
->GetError() == ERRCODE_NONE
&& ( bError
|| !xLockBytes
->getInputStream().is() ) )
1701 DBG_ERROR("No InputStream, but no error set!" );
1702 xLockBytes
->SetError( ERRCODE_IO_GENERAL
);
1708 UcbLockBytesRef
UcbLockBytes::CreateLockBytes( const Reference
< XContent
>& xContent
, const Sequence
< PropertyValue
>& rProps
,
1709 StreamMode eOpenMode
, const Reference
< XInteractionHandler
>& xInteractionHandler
, UcbLockBytesHandler
* pHandler
)
1711 if( !xContent
.is() )
1714 UcbLockBytesRef xLockBytes
= new UcbLockBytes( pHandler
);
1715 xLockBytes
->SetSynchronMode( !pHandler
);
1716 Reference
< XActiveDataControl
> xSink
;
1717 if ( eOpenMode
& STREAM_WRITE
)
1718 xSink
= (XActiveDataControl
*) new UcbStreamer_Impl( xLockBytes
);
1720 xSink
= (XActiveDataControl
*) new UcbDataSink_Impl( xLockBytes
);
1722 if ( rProps
.getLength() )
1724 Reference
< XCommandProcessor
> xProcessor( xContent
, UNO_QUERY
);
1726 aCommand
.Name
= ::rtl::OUString::createFromAscii("setPropertyValues");
1727 aCommand
.Handle
= -1; /* unknown */
1728 aCommand
.Argument
<<= rProps
;
1729 xProcessor
->execute( aCommand
, 0, Reference
< XCommandEnvironment
>() );
1732 OpenCommandArgument2 aArgument
;
1733 aArgument
.Sink
= xSink
;
1734 aArgument
.Mode
= OpenMode::DOCUMENT
;
1737 aCommand
.Name
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("open") );
1738 aCommand
.Argument
<<= aArgument
;
1740 Reference
< XProgressHandler
> xProgressHdl
= new ProgressHandler_Impl( LINK( &xLockBytes
, UcbLockBytes
, DataAvailHdl
) );
1742 sal_Bool bError
= UCBOpenContentSync( xLockBytes
,
1746 xInteractionHandler
,
1750 if ( xLockBytes
->GetError() == ERRCODE_NONE
&& ( bError
|| !xLockBytes
->getInputStream().is() ) )
1752 DBG_ERROR("No InputStream, but no error set!" );
1753 xLockBytes
->SetError( ERRCODE_IO_GENERAL
);