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: ftpcontent.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_ucb.hxx"
34 /**************************************************************************
36 **************************************************************************
38 *************************************************************************/
39 #include <com/sun/star/beans/PropertyAttribute.hpp>
41 #include "ftpdynresultset.hxx"
42 #include "ftpresultsetfactory.hxx"
43 #include "ftpresultsetI.hxx"
44 #include "ftpcontent.hxx"
45 #include "ftpcontentprovider.hxx"
46 #include "ftpinpstr.hxx"
47 #include "ftpdirp.hxx"
48 #include "ftpcontentidentifier.hxx"
49 #include "ftpcfunc.hxx"
50 #include "ftpstrcont.hxx"
51 #include "ftpintreq.hxx"
55 #include <rtl/memory.h>
57 #include <curl/easy.h>
58 #include <ucbhelper/cancelcommandexecution.hxx>
59 #include <ucbhelper/contentidentifier.hxx>
60 #include <ucbhelper/propertyvalueset.hxx>
61 #include <ucbhelper/contentidentifier.hxx>
62 #include <ucbhelper/cancelcommandexecution.hxx>
63 #include <ucbhelper/simpleauthenticationrequest.hxx>
64 #include <com/sun/star/lang/IllegalAccessException.hpp>
65 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
66 #include <com/sun/star/beans/UnknownPropertyException.hpp>
67 #include <com/sun/star/beans/Property.hpp>
68 #include <com/sun/star/beans/PropertyValue.hpp>
69 #include <com/sun/star/ucb/XCommandInfo.hpp>
70 #include <com/sun/star/io/XActiveDataSink.hpp>
71 #include <com/sun/star/io/XOutputStream.hpp>
72 #include <com/sun/star/io/XActiveDataStreamer.hpp>
73 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
74 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
75 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
76 #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
77 #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
78 #include <com/sun/star/ucb/InteractiveIOException.hpp>
79 #include <com/sun/star/ucb/MissingPropertiesException.hpp>
80 #include <com/sun/star/ucb/MissingInputStreamException.hpp>
81 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
82 #include <com/sun/star/ucb/NameClashException.hpp>
83 //#include <com/sun/star/ucb/NameClash.hpp>
84 #include <com/sun/star/ucb/OpenMode.hpp>
85 #include <com/sun/star/ucb/IOErrorCode.hpp>
88 using namespace com::sun::star::task
;
89 using namespace com::sun::star::container
;
90 using namespace com::sun::star::lang
;
91 using namespace com::sun::star::uno
;
92 using namespace com::sun::star::ucb
;
93 using namespace com::sun::star::beans
;
94 using namespace com::sun::star::io
;
95 using namespace com::sun::star::sdbc
;
99 //=========================================================================
100 //=========================================================================
102 // Content Implementation.
104 //=========================================================================
105 //=========================================================================
107 FTPContent::FTPContent( const Reference
< XMultiServiceFactory
>& rxSMgr
,
108 FTPContentProvider
* pProvider
,
109 const Reference
< XContentIdentifier
>& Identifier
)
110 : ContentImplHelper(rxSMgr
,pProvider
,Identifier
),
112 m_aFTPURL(Identifier
->getContentIdentifier(),
120 FTPContent::FTPContent( const Reference
< XMultiServiceFactory
>& rxSMgr
,
121 FTPContentProvider
* pProvider
,
122 const Reference
< XContentIdentifier
>& Identifier
,
123 const FTPURL
& aFTPURL
)
124 : ContentImplHelper(rxSMgr
,pProvider
,Identifier
),
134 FTPContent::FTPContent( const Reference
< XMultiServiceFactory
>& rxSMgr
,
135 FTPContentProvider
* pProvider
,
136 const Reference
< XContentIdentifier
>& Identifier
,
137 const ContentInfo
& Info
)
138 : ContentImplHelper(rxSMgr
,pProvider
,Identifier
),
140 m_aFTPURL(Identifier
->getContentIdentifier(),
150 //=========================================================================
152 FTPContent::~FTPContent()
157 //=========================================================================
159 // XInterface methods.
161 //=========================================================================
163 XINTERFACE_IMPL_6( FTPContent
,
171 //=========================================================================
173 // XTypeProvider methods.
175 //=========================================================================
177 XTYPEPROVIDER_IMPL_6( FTPContent
,
185 //=========================================================================
187 // XServiceInfo methods.
189 //=========================================================================
191 // needed, because the service shall not be creatable!!
192 #undef XSERVICEINFO_CREATE_INSTANCE_IMPL
193 #define XSERVICEINFO_CREATE_INSTANCE_IMPL( Class )
195 XSERVICEINFO_IMPL_1( FTPContent
,
196 rtl::OUString::createFromAscii(
197 "com.sun.star.comp.FTPContent"),
198 rtl::OUString::createFromAscii(
199 "com.sun.star.ucb.FTPContent"));
203 //=========================================================================
207 //=========================================================================
210 rtl::OUString SAL_CALL
FTPContent::getContentType()
211 throw( RuntimeException
)
213 return rtl::OUString::createFromAscii(FTP_CONTENT_TYPE
);
217 //=========================================================================
219 // XCommandProcessor methods.
221 //=========================================================================
225 void SAL_CALL
FTPContent::abort( sal_Int32
/*CommandId*/ )
226 throw( RuntimeException
)
232 /***************************************************************************/
234 /* Interne Implklasse */
236 /***************************************************************************/
239 class ResultSetFactoryI
240 : public ResultSetFactory
244 ResultSetFactoryI(const Reference
<XMultiServiceFactory
>& xSMgr
,
245 const Reference
<XContentProvider
>& xProvider
,
247 const Sequence
<Property
>& seq
,
248 const Sequence
<NumberedSortingInfo
>& seqSort
,
249 const std::vector
<FTPDirentry
>& dirvec
)
251 m_xProvider(xProvider
),
252 m_nOpenMode(nOpenMode
),
259 virtual ResultSetBase
* createResultSet()
261 return new ResultSetI(m_xSMgr
,
271 Reference
< XMultiServiceFactory
> m_xSMgr
;
272 Reference
< XContentProvider
> m_xProvider
;
273 sal_Int32 m_nOpenMode
;
274 Sequence
< Property
> m_seq
;
275 Sequence
< NumberedSortingInfo
> m_seqSort
;
276 std::vector
<FTPDirentry
> m_dirvec
;
281 //=========================================================================
283 // XCommandProcessor methods.
285 //=========================================================================
287 enum ACTION
{ NOACTION
,
288 THROWAUTHENTICATIONREQUEST
,
290 THROWINTERACTIVECONNECT
,
298 Any SAL_CALL
FTPContent::execute(
299 const Command
& aCommand
,
300 sal_Int32
/*CommandId*/,
302 XCommandEnvironment
>& Environment
306 CommandAbortedException
,
310 ACTION
action(NOACTION
);
315 if(action
== THROWAUTHENTICATIONREQUEST
) {
316 // try to get a continuation first
317 rtl::OUString aRealm
,aPassword
,aAccount
;
318 m_pFCP
->forHost(m_aFTPURL
.host(),
320 m_aFTPURL
.username(),
323 rtl::Reference
<ucbhelper::SimpleAuthenticationRequest
>
324 p( new ucbhelper::SimpleAuthenticationRequest(
325 m_aFTPURL
.ident(false, false),
326 m_aFTPURL
.host(), // ServerName
327 ucbhelper::SimpleAuthenticationRequest::ENTITY_NA
,
329 ucbhelper::SimpleAuthenticationRequest
331 m_aFTPURL
.username(),
332 ucbhelper::SimpleAuthenticationRequest
336 Reference
<XInteractionHandler
> xInteractionHandler
;
338 xInteractionHandler
=
339 Environment
->getInteractionHandler();
341 if( xInteractionHandler
.is()) {
342 xInteractionHandler
->handle(p
.get());
344 Reference
<XInterface
> xSelection(
345 p
->getSelection().get());
347 if(Reference
<XInteractionRetry
>(
348 xSelection
,UNO_QUERY
).is())
350 else if(Reference
<XInteractionSupplyAuthentication
>(
351 xSelection
,UNO_QUERY
).is()) {
355 m_aFTPURL
.username(),
356 p
->getAuthenticationSupplier()->getPassword(),
361 aRet
= p
->getRequest();
364 // if(aCommand.Name.compareToAscii(
365 // "getPropertyValues") == 0 &&
366 // action != NOACTION) {
367 // // It is not allowed to throw if
368 // // command is getPropertyValues
369 // rtl::Reference<ucbhelper::PropertyValueSet> xRow =
370 // new ucbhelper::PropertyValueSet(m_xSMgr);
371 // Sequence<Property> Properties;
372 // aCommand.Argument >>= Properties;
373 // for(int i = 0; i < Properties.getLength(); ++i)
374 // xRow->appendVoid(Properties[i]);
375 // aRet <<= Reference<XRow>(xRow.get());
379 if(action
== THROWAUTHENTICATIONREQUEST
) {
380 ucbhelper::cancelCommandExecution(
382 Reference
<XCommandEnvironment
>(0));
383 } else if(action
== THROWACCESSDENIED
) {
384 Sequence
<Any
> seq(1);
387 rtl::OUString::createFromAscii("Uri");
389 value
.Value
<<= m_aFTPURL
.ident(false,false);
390 value
.State
= PropertyState_DIRECT_VALUE
;
392 ucbhelper::cancelCommandExecution(
393 IOErrorCode_ACCESS_DENIED
,
396 } else if(action
== THROWINTERACTIVECONNECT
) {
397 InteractiveNetworkConnectException
399 excep
.Server
= m_aFTPURL
.host();
401 ucbhelper::cancelCommandExecution(
404 } else if(action
== THROWRESOLVENAME
) {
405 InteractiveNetworkResolveNameException
407 excep
.Server
= m_aFTPURL
.host();
409 ucbhelper::cancelCommandExecution(
412 } else if(action
== THROWNOFILE
) {
413 Sequence
<Any
> seq(1);
416 rtl::OUString::createFromAscii("Uri");
418 value
.Value
<<= m_aFTPURL
.ident(false,false);
419 value
.State
= PropertyState_DIRECT_VALUE
;
421 ucbhelper::cancelCommandExecution(
425 } else if(action
== THROWQUOTE
||
426 action
== THROWGENERAL
) {
427 ucbhelper::cancelCommandExecution(
434 if(aCommand
.Name
.compareToAscii("getPropertyValues") == 0) {
435 Sequence
<Property
> Properties
;
436 if(!(aCommand
.Argument
>>= Properties
))
438 aRet
<<= IllegalArgumentException();
439 ucbhelper::cancelCommandExecution(aRet
,Environment
);
442 aRet
<<= getPropertyValues(Properties
,Environment
);
444 else if(aCommand
.Name
.compareToAscii("setPropertyValues") == 0)
446 Sequence
<PropertyValue
> propertyValues
;
448 if( ! ( aCommand
.Argument
>>= propertyValues
) ) {
449 aRet
<<= IllegalArgumentException();
450 ucbhelper::cancelCommandExecution(aRet
,Environment
);
453 aRet
<<= setPropertyValues(propertyValues
);
455 else if(aCommand
.Name
.compareToAscii("getCommandInfo") == 0) {
456 // Note: Implemented by base class.
457 aRet
<<= getCommandInfo(Environment
);
459 else if(aCommand
.Name
.compareToAscii("getPropertySetInfo") == 0) {
460 // Note: Implemented by base class.
461 aRet
<<= getPropertySetInfo(Environment
);
463 else if(aCommand
.Name
.compareToAscii( "insert" ) == 0)
465 InsertCommandArgument aInsertArgument
;
466 if ( ! ( aCommand
.Argument
>>= aInsertArgument
) ) {
467 aRet
<<= IllegalArgumentException();
468 ucbhelper::cancelCommandExecution(aRet
,Environment
);
470 insert(aInsertArgument
,Environment
);
472 else if(aCommand
.Name
.compareToAscii("delete") == 0) {
476 else if(aCommand
.Name
.compareToAscii( "open" ) == 0) {
477 OpenCommandArgument2 aOpenCommand
;
478 if ( !( aCommand
.Argument
>>= aOpenCommand
) ) {
479 aRet
<<= IllegalArgumentException();
480 ucbhelper::cancelCommandExecution(aRet
,Environment
);
483 if(aOpenCommand
.Mode
== OpenMode::DOCUMENT
) {
484 // Open as a document
485 Reference
<XActiveDataSink
>
486 xActiveDataSink(aOpenCommand
.Sink
,UNO_QUERY
);
487 Reference
< XOutputStream
>
488 xOutputStream(aOpenCommand
.Sink
,UNO_QUERY
);
490 if(xActiveDataSink
.is()) {
491 xActiveDataSink
->setInputStream(
492 new FTPInputStream(m_aFTPURL
.open()));
494 else if(xOutputStream
.is()) {
495 Reference
<XInputStream
> xStream(
496 new FTPInputStream(m_aFTPURL
.open()));
497 Sequence
<sal_Int8
> byte_seq(4096);
498 sal_Int32 n
= 1000; // value does not matter here
500 n
= xStream
->readBytes(byte_seq
,4096);
505 if(byte_seq
.getLength() != n
)
507 xOutputStream
->writeBytes(byte_seq
);
508 } catch(const NotConnectedException
&) {
510 } catch(const BufferSizeExceededException
&) {
512 } catch(const IOException
&) {
517 Sequence
<Any
> seq(1);
520 rtl::OUString::createFromAscii("Uri");
522 value
.Value
<<= m_aFTPURL
.ident(false,false);
523 value
.State
= PropertyState_DIRECT_VALUE
;
525 ucbhelper::cancelCommandExecution(
532 aRet
<<= UnsupportedDataSinkException();
533 ucbhelper::cancelCommandExecution(aRet
,Environment
);
536 else if(aOpenCommand
.Mode
== OpenMode::ALL
||
537 aOpenCommand
.Mode
== OpenMode::DOCUMENTS
||
538 aOpenCommand
.Mode
== OpenMode::FOLDERS
) {
539 std::vector
<FTPDirentry
> resvec
=
540 m_aFTPURL
.list(sal_Int16(aOpenCommand
.Mode
));
541 Reference
< XDynamicResultSet
> xSet
542 = new DynamicResultSet(
547 new ResultSetFactoryI(m_xSMgr
,
550 aOpenCommand
.Properties
,
551 aOpenCommand
.SortingInfo
,
555 else if(aOpenCommand
.Mode
==
556 OpenMode::DOCUMENT_SHARE_DENY_NONE
||
558 OpenMode::DOCUMENT_SHARE_DENY_WRITE
) {
559 // Unsupported OpenMode
560 aRet
<<= UnsupportedOpenModeException();
561 ucbhelper::cancelCommandExecution(aRet
,Environment
);
564 // IllegalArgumentException:: No OpenMode
565 aRet
<<= IllegalArgumentException();
566 ucbhelper::cancelCommandExecution(aRet
,Environment
);
570 aRet
<<= UnsupportedCommandException();
571 ucbhelper::cancelCommandExecution(aRet
,Environment
);
575 } catch(const curl_exception
& e
) {
576 if(e
.code() == CURLE_COULDNT_CONNECT
)
577 action
= THROWINTERACTIVECONNECT
;
578 else if(e
.code() == CURLE_COULDNT_RESOLVE_HOST
)
579 action
= THROWRESOLVENAME
;
580 else if(e
.code() == CURLE_FTP_USER_PASSWORD_INCORRECT
||
581 e
.code() == CURLE_BAD_PASSWORD_ENTERED
||
582 e
.code() == CURLE_FTP_WEIRD_PASS_REPLY
)
583 action
= THROWAUTHENTICATIONREQUEST
;
584 else if(e
.code() == CURLE_FTP_ACCESS_DENIED
)
585 action
= THROWACCESSDENIED
;
586 else if(e
.code() == CURLE_FTP_QUOTE_ERROR
)
588 else if(e
.code() == CURLE_FTP_COULDNT_RETR_FILE
)
589 action
= THROWNOFILE
;
591 // nothing known about the course of the error
592 action
= THROWGENERAL
;
596 #define FTP_FILE rtl::OUString::createFromAscii( \
598 "vnd.sun.staroffice.ftp-file")
600 #define FTP_FOLDER rtl::OUString::createFromAscii( \
602 "vnd.sun.staroffice.ftp-folder")
604 Sequence
<ContentInfo
> SAL_CALL
605 FTPContent::queryCreatableContentsInfo( )
606 throw (RuntimeException
)
608 Sequence
< ContentInfo
> seq(2);
610 seq
[0].Type
= FTP_FILE
;
611 seq
[0].Attributes
= ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
612 | ContentInfoAttribute::KIND_DOCUMENT
;
613 Sequence
< Property
> props( 1 );
615 rtl::OUString::createFromAscii( "Title" ),
617 getCppuType( static_cast< rtl::OUString
* >( 0 ) ),
618 PropertyAttribute::MAYBEVOID
619 | PropertyAttribute::BOUND
);
620 seq
[0].Properties
= props
;
623 seq
[1].Type
= FTP_FOLDER
;
624 seq
[1].Attributes
= ContentInfoAttribute::KIND_FOLDER
;
625 seq
[1].Properties
= props
;
631 Reference
<XContent
> SAL_CALL
632 FTPContent::createNewContent( const ContentInfo
& Info
)
633 throw (RuntimeException
)
635 if(Info
.Type
.equalsAscii("application/"
636 "vnd.sun.staroffice.ftp-file") ||
637 Info
.Type
.equalsAscii("application/"
638 "vnd.sun.staroffice.ftp-folder"))
639 return new FTPContent(m_xSMgr
,
643 return Reference
<XContent
>(0);
649 Reference
<XInterface
> SAL_CALL
650 FTPContent::getParent( )
651 throw (RuntimeException
)
653 Reference
<XContentIdentifier
>
654 xIdent(new FTPContentIdentifier(m_aFTPURL
.parent(false)));
655 Reference
<XContent
> xContent(m_xProvider
->queryContent(xIdent
));
656 return Reference
<XInterface
>(xContent
,UNO_QUERY
);
661 FTPContent::setParent(const Reference
<XInterface
>& /*Parent*/ )
662 throw (NoSupportException
,
665 throw NoSupportException();
670 rtl::OUString
FTPContent::getParentURL()
672 return m_aFTPURL
.parent();
681 InsertData(const Reference
<XInputStream
>& xInputStream
)
682 : m_xInputStream(xInputStream
) { }
683 virtual ~InsertData() {}
685 // returns the number of bytes actually read
686 virtual sal_Int32
read(sal_Int8
*dest
,sal_Int32 nBytesRequested
);
690 Reference
<XInputStream
> m_xInputStream
;
695 sal_Int32
InsertData::read(sal_Int8
*dest
,sal_Int32 nBytesRequested
)
699 if(m_xInputStream
.is()) {
700 Sequence
<sal_Int8
> seq(nBytesRequested
);
701 m
= m_xInputStream
->readBytes(seq
,nBytesRequested
);
702 rtl_copyMemory(dest
,seq
.getConstArray(),m
);
708 void FTPContent::insert(const InsertCommandArgument
& aInsertCommand
,
709 const Reference
<XCommandEnvironment
>& Env
)
711 osl::MutexGuard
aGuard(m_aMutex
);
713 if(m_bInserted
&& !m_bTitleSet
) {
714 MissingPropertiesException excep
;
715 excep
.Properties
.realloc(1);
716 excep
.Properties
[0] = rtl::OUString::createFromAscii("Title");
717 Any aAny
; aAny
<<= excep
;
718 ucbhelper::cancelCommandExecution(aAny
,Env
);
722 m_aInfo
.Type
== FTP_FILE
&&
723 !aInsertCommand
.Data
.is())
725 MissingInputStreamException excep
;
726 Any aAny
; aAny
<<= excep
;
727 ucbhelper::cancelCommandExecution(aAny
,Env
);
730 bool bReplace(aInsertCommand
.ReplaceExisting
);
734 if(m_aInfo
.Type
== FTP_FILE
) {
735 InsertData
data(aInsertCommand
.Data
);
736 m_aFTPURL
.insert(bReplace
,&data
);
737 } else if(m_aInfo
.Type
== FTP_FOLDER
)
738 m_aFTPURL
.mkdir(bReplace
);
739 } catch(const curl_exception
& e
) {
740 if(e
.code() == FILE_EXIST_DURING_INSERT
||
741 e
.code() == FOLDER_EXIST_DURING_INSERT
) {
742 // Deprecated, not used anymore:
743 NameClashException excep
;
744 excep
.Name
= m_aFTPURL
.child();
747 ucbhelper::cancelCommandExecution(aAny
,Env
);
748 } else if(e
.code() == FOLDER_MIGHT_EXIST_DURING_INSERT
||
749 e
.code() == FILE_MIGHT_EXIST_DURING_INSERT
) {
751 Reference
<XInteractionHandler
> xInt
;
753 xInt
= Env
->getInteractionHandler();
755 UnsupportedNameClashException excep
;
756 excep
.NameClash
= 0; //NameClash::ERROR;
761 ucbhelper::cancelCommandExecution(aAny
,Env
);
764 XInteractionRequestImpl
* p
=
765 new XInteractionRequestImpl(m_aFTPURL
.child());
766 Reference
<XInteractionRequest
> req(p
);
779 // May not be reached, because both mkdir and insert can throw curl-
787 Reference
< XRow
> FTPContent::getPropertyValues(
788 const Sequence
< Property
>& seqProp
,
789 const Reference
<XCommandEnvironment
>& /*environment*/
792 rtl::Reference
<ucbhelper::PropertyValueSet
> xRow
=
793 new ucbhelper::PropertyValueSet(m_xSMgr
);
795 FTPDirentry aDirEntry
= m_aFTPURL
.direntry();
797 for(sal_Int32 i
= 0; i
< seqProp
.getLength(); ++i
) {
798 const rtl::OUString
& Name
= seqProp
[i
].Name
;
799 if(Name
.compareToAscii("Title") == 0)
800 xRow
->appendString(seqProp
[i
],aDirEntry
.m_aName
);
801 else if(aDirEntry
.m_nMode
!= INETCOREFTP_FILEMODE_UNKNOWN
) {
802 if(Name
.compareToAscii("ContentType") == 0)
803 xRow
->appendString(seqProp
[i
],
804 aDirEntry
.m_nMode
&INETCOREFTP_FILEMODE_ISDIR
807 else if(Name
.compareToAscii("IsReadOnly") == 0)
808 xRow
->appendBoolean(seqProp
[i
],
810 & INETCOREFTP_FILEMODE_WRITE
813 else if(Name
.compareToAscii("IsDocument") == 0)
814 xRow
->appendBoolean(seqProp
[i
],
815 ! sal_Bool(aDirEntry
.m_nMode
&
816 INETCOREFTP_FILEMODE_ISDIR
));
817 else if(Name
.compareToAscii("IsFolder") == 0)
818 xRow
->appendBoolean(seqProp
[i
],
819 sal_Bool(aDirEntry
.m_nMode
&
820 INETCOREFTP_FILEMODE_ISDIR
));
821 else if(Name
.compareToAscii("Size") == 0)
822 xRow
->appendLong(seqProp
[i
],
824 else if(Name
.compareToAscii("DateCreated") == 0)
825 xRow
->appendTimestamp(seqProp
[i
],
828 xRow
->appendVoid(seqProp
[i
]);
830 xRow
->appendVoid(seqProp
[i
]);
833 return Reference
<XRow
>(xRow
.get());
838 Sequence
<Any
> FTPContent::setPropertyValues(
839 const Sequence
<PropertyValue
>& seqPropVal
)
841 Sequence
<Property
> props
=
842 getProperties(Reference
<XCommandEnvironment
>(0));
844 Sequence
<Any
> ret(seqPropVal
.getLength());
845 Sequence
<PropertyChangeEvent
> evt
;
847 osl::MutexGuard
aGuard(m_aMutex
);
848 for(sal_Int32 i
= 0; i
< ret
.getLength(); ++i
) {
849 if(seqPropVal
[i
].Name
.equalsAscii("Title")) {
851 if(!(seqPropVal
[i
].Value
>>= Title
)) {
852 ret
[i
] <<= IllegalTypeException();
854 } else if(!Title
.getLength()) {
855 ret
[i
] <<= IllegalArgumentException();
860 m_aFTPURL
.child(Title
);
862 new FTPContentIdentifier(m_aFTPURL
.ident(false,false));
866 rtl::OUString OldTitle
= m_aFTPURL
.ren(Title
);
868 evt
[0].PropertyName
=
869 rtl::OUString::createFromAscii("Title");
870 evt
[0].Further
= false;
871 evt
[0].PropertyHandle
= -1;
872 evt
[0].OldValue
<<= OldTitle
;
873 evt
[0].NewValue
<<= Title
;
874 } catch(const curl_exception
&) {
875 InteractiveIOException excep
;
876 // any better possibility here?
877 // ( the error code is always CURLE_FTP_QUOTE_ERROR )
878 excep
.Code
= IOErrorCode_ACCESS_DENIED
;
882 // either not unknown or illegal
883 ret
[i
] <<= UnknownPropertyException();
884 for(sal_Int32 j
= 0; j
< props
.getLength(); ++j
)
885 if(props
[j
].Name
== seqPropVal
[i
].Name
) {
886 ret
[i
] <<= IllegalAccessException();
892 if(evt
.getLength()) {
894 notifyPropertiesChange(evt
);
895 exchange(new FTPContentIdentifier(m_aFTPURL
.ident(false,false)));