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 .
21 /**************************************************************************
23 **************************************************************************
25 *************************************************************************/
26 #include <com/sun/star/beans/PropertyAttribute.hpp>
28 #include "ftpdynresultset.hxx"
29 #include "ftpresultsetfactory.hxx"
30 #include "ftpresultsetI.hxx"
31 #include "ftpcontent.hxx"
32 #include "ftpcontentprovider.hxx"
33 #include "ftpdirp.hxx"
34 #include "ftpcontentidentifier.hxx"
35 #include "ftpcfunc.hxx"
36 #include "ftpstrcont.hxx"
37 #include "ftpintreq.hxx"
43 #include <curl/easy.h>
44 #include <comphelper/processfactory.hxx>
45 #include <ucbhelper/cancelcommandexecution.hxx>
46 #include <ucbhelper/contentidentifier.hxx>
47 #include <ucbhelper/fd_inputstream.hxx>
48 #include <ucbhelper/propertyvalueset.hxx>
49 #include <ucbhelper/contentidentifier.hxx>
50 #include <ucbhelper/cancelcommandexecution.hxx>
51 #include <ucbhelper/simpleauthenticationrequest.hxx>
52 #include <com/sun/star/lang/IllegalAccessException.hpp>
53 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
54 #include <com/sun/star/beans/UnknownPropertyException.hpp>
55 #include <com/sun/star/beans/Property.hpp>
56 #include <com/sun/star/beans/PropertyValue.hpp>
57 #include <com/sun/star/ucb/XCommandInfo.hpp>
58 #include <com/sun/star/io/XActiveDataSink.hpp>
59 #include <com/sun/star/io/XOutputStream.hpp>
60 #include <com/sun/star/io/XActiveDataStreamer.hpp>
61 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
62 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
63 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
64 #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
65 #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
66 #include <com/sun/star/ucb/InteractiveIOException.hpp>
67 #include <com/sun/star/ucb/MissingPropertiesException.hpp>
68 #include <com/sun/star/ucb/MissingInputStreamException.hpp>
69 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
70 #include <com/sun/star/ucb/NameClashException.hpp>
71 #include <com/sun/star/ucb/OpenMode.hpp>
72 #include <com/sun/star/ucb/IOErrorCode.hpp>
75 using namespace com::sun::star::task
;
76 using namespace com::sun::star::container
;
77 using namespace com::sun::star::lang
;
78 using namespace com::sun::star::uno
;
79 using namespace com::sun::star::ucb
;
80 using namespace com::sun::star::beans
;
81 using namespace com::sun::star::io
;
82 using namespace com::sun::star::sdbc
;
86 //=========================================================================
87 //=========================================================================
89 // Content Implementation.
91 //=========================================================================
92 //=========================================================================
94 FTPContent::FTPContent( const Reference
< XComponentContext
>& rxContext
,
95 FTPContentProvider
* pProvider
,
96 const Reference
< XContentIdentifier
>& Identifier
,
97 const FTPURL
& aFTPURL
)
98 : ContentImplHelper(rxContext
,pProvider
,Identifier
),
108 FTPContent::FTPContent( const Reference
< XComponentContext
>& rxContext
,
109 FTPContentProvider
* pProvider
,
110 const Reference
< XContentIdentifier
>& Identifier
,
111 const ContentInfo
& Info
)
112 : ContentImplHelper(rxContext
,pProvider
,Identifier
),
114 m_aFTPURL(Identifier
->getContentIdentifier(),
124 //=========================================================================
126 FTPContent::~FTPContent()
131 //=========================================================================
133 // XInterface methods.
135 //=========================================================================
137 XINTERFACE_IMPL_6( FTPContent
,
145 //=========================================================================
147 // XTypeProvider methods.
149 //=========================================================================
151 XTYPEPROVIDER_IMPL_6( FTPContent
,
159 //=========================================================================
161 // XServiceInfo methods.
163 //=========================================================================
165 // needed, because the service shall not be creatable!!
166 #undef XSERVICEINFO_CREATE_INSTANCE_IMPL
167 #define XSERVICEINFO_CREATE_INSTANCE_IMPL( Class )
169 XSERVICEINFO_IMPL_1( FTPContent
,
170 rtl::OUString( "com.sun.star.comp.FTPContent"),
171 rtl::OUString( "com.sun.star.ucb.FTPContent"));
175 //=========================================================================
179 //=========================================================================
182 rtl::OUString SAL_CALL
FTPContent::getContentType()
183 throw( RuntimeException
)
185 return rtl::OUString(FTP_CONTENT_TYPE
);
189 //=========================================================================
191 // XCommandProcessor methods.
193 //=========================================================================
197 void SAL_CALL
FTPContent::abort( sal_Int32
/*CommandId*/ )
198 throw( RuntimeException
)
204 /***************************************************************************/
206 /* Internal implementation class. */
208 /***************************************************************************/
211 class ResultSetFactoryI
212 : public ResultSetFactory
216 ResultSetFactoryI(const Reference
<XComponentContext
>& rxContext
,
217 const Reference
<XContentProvider
>& xProvider
,
219 const Sequence
<Property
>& seq
,
220 const Sequence
<NumberedSortingInfo
>& seqSort
,
221 const std::vector
<FTPDirentry
>& dirvec
)
222 : m_xContext(rxContext
),
223 m_xProvider(xProvider
),
224 m_nOpenMode(nOpenMode
),
231 virtual ResultSetBase
* createResultSet()
233 return new ResultSetI(m_xContext
,
243 Reference
< XComponentContext
> m_xContext
;
244 Reference
< XContentProvider
> m_xProvider
;
245 sal_Int32 m_nOpenMode
;
246 Sequence
< Property
> m_seq
;
247 Sequence
< NumberedSortingInfo
> m_seqSort
;
248 std::vector
<FTPDirentry
> m_dirvec
;
253 //=========================================================================
255 // XCommandProcessor methods.
257 //=========================================================================
259 enum ACTION
{ NOACTION
,
260 THROWAUTHENTICATIONREQUEST
,
262 THROWINTERACTIVECONNECT
,
270 Any SAL_CALL
FTPContent::execute(
271 const Command
& aCommand
,
272 sal_Int32
/*CommandId*/,
274 XCommandEnvironment
>& Environment
278 CommandAbortedException
,
282 ACTION
action(NOACTION
);
287 if(action
== THROWAUTHENTICATIONREQUEST
) {
288 // try to get a continuation first
289 rtl::OUString aRealm
,aPassword
,aAccount
;
290 m_pFCP
->forHost(m_aFTPURL
.host(),
292 m_aFTPURL
.username(),
295 rtl::Reference
<ucbhelper::SimpleAuthenticationRequest
>
296 p( new ucbhelper::SimpleAuthenticationRequest(
297 m_aFTPURL
.ident(false, false),
298 m_aFTPURL
.host(), // ServerName
299 ucbhelper::SimpleAuthenticationRequest::ENTITY_NA
,
301 ucbhelper::SimpleAuthenticationRequest
303 m_aFTPURL
.username(),
304 ucbhelper::SimpleAuthenticationRequest
308 Reference
<XInteractionHandler
> xInteractionHandler
;
310 xInteractionHandler
=
311 Environment
->getInteractionHandler();
313 if( xInteractionHandler
.is()) {
314 xInteractionHandler
->handle(p
.get());
316 Reference
<XInterface
> xSelection(
317 p
->getSelection().get());
319 if(Reference
<XInteractionRetry
>(
320 xSelection
,UNO_QUERY
).is())
322 else if(Reference
<XInteractionSupplyAuthentication
>(
323 xSelection
,UNO_QUERY
).is()) {
327 m_aFTPURL
.username(),
328 p
->getAuthenticationSupplier()->getPassword(),
333 aRet
= p
->getRequest();
336 // if(aCommand.Name.compareToAscii(
337 // "getPropertyValues") == 0 &&
338 // action != NOACTION) {
339 // // It is not allowed to throw if
340 // // command is getPropertyValues
341 // rtl::Reference<ucbhelper::PropertyValueSet> xRow =
342 // new ucbhelper::PropertyValueSet(m_xSMgr);
343 // Sequence<Property> Properties;
344 // aCommand.Argument >>= Properties;
345 // for(int i = 0; i < Properties.getLength(); ++i)
346 // xRow->appendVoid(Properties[i]);
347 // aRet <<= Reference<XRow>(xRow.get());
356 case THROWAUTHENTICATIONREQUEST
:
357 ucbhelper::cancelCommandExecution(
359 Reference
<XCommandEnvironment
>(0));
362 case THROWACCESSDENIED
:
364 Sequence
<Any
> seq(1);
366 value
.Name
= rtl::OUString("Uri");
368 value
.Value
<<= m_aFTPURL
.ident(false,false);
369 value
.State
= PropertyState_DIRECT_VALUE
;
371 ucbhelper::cancelCommandExecution(
372 IOErrorCode_ACCESS_DENIED
,
377 case THROWINTERACTIVECONNECT
:
379 InteractiveNetworkConnectException excep
;
380 excep
.Server
= m_aFTPURL
.host();
382 ucbhelper::cancelCommandExecution(
387 case THROWRESOLVENAME
:
389 InteractiveNetworkResolveNameException excep
;
390 excep
.Server
= m_aFTPURL
.host();
392 ucbhelper::cancelCommandExecution(
399 Sequence
<Any
> seq(1);
401 value
.Name
= rtl::OUString("Uri");
403 value
.Value
<<= m_aFTPURL
.ident(false,false);
404 value
.State
= PropertyState_DIRECT_VALUE
;
406 ucbhelper::cancelCommandExecution(
414 ucbhelper::cancelCommandExecution(
421 if(aCommand
.Name
.compareToAscii("getPropertyValues") == 0) {
422 Sequence
<Property
> Properties
;
423 if(!(aCommand
.Argument
>>= Properties
))
425 aRet
<<= IllegalArgumentException(
426 rtl::OUString( "Wrong argument type!" ),
427 static_cast< cppu::OWeakObject
* >(this),
429 ucbhelper::cancelCommandExecution(aRet
,Environment
);
432 aRet
<<= getPropertyValues(Properties
,Environment
);
434 else if(aCommand
.Name
.compareToAscii("setPropertyValues") == 0)
436 Sequence
<PropertyValue
> propertyValues
;
438 if( ! ( aCommand
.Argument
>>= propertyValues
) ) {
439 aRet
<<= IllegalArgumentException(
440 rtl::OUString( "Wrong argument type!" ),
441 static_cast< cppu::OWeakObject
* >(this),
443 ucbhelper::cancelCommandExecution(aRet
,Environment
);
446 aRet
<<= setPropertyValues(propertyValues
);
448 else if(aCommand
.Name
.compareToAscii("getCommandInfo") == 0) {
449 // Note: Implemented by base class.
450 aRet
<<= getCommandInfo(Environment
);
452 else if(aCommand
.Name
.compareToAscii("getPropertySetInfo") == 0) {
453 // Note: Implemented by base class.
454 aRet
<<= getPropertySetInfo(Environment
);
456 else if(aCommand
.Name
.compareToAscii( "insert" ) == 0)
458 InsertCommandArgument aInsertArgument
;
459 if ( ! ( aCommand
.Argument
>>= aInsertArgument
) ) {
460 aRet
<<= IllegalArgumentException(
461 rtl::OUString( "Wrong argument type!" ),
462 static_cast< cppu::OWeakObject
* >(this),
464 ucbhelper::cancelCommandExecution(aRet
,Environment
);
466 insert(aInsertArgument
,Environment
);
468 else if(aCommand
.Name
.compareToAscii("delete") == 0) {
472 else if(aCommand
.Name
.compareToAscii( "open" ) == 0) {
473 OpenCommandArgument2 aOpenCommand
;
474 if ( !( aCommand
.Argument
>>= aOpenCommand
) ) {
475 aRet
<<= IllegalArgumentException(
476 rtl::OUString( "Wrong argument type!" ),
477 static_cast< cppu::OWeakObject
* >(this),
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 ucbhelper::FdInputStream(m_aFTPURL
.open()));
494 else if(xOutputStream
.is()) {
495 Reference
<XInputStream
> xStream(
496 new ucbhelper::FdInputStream(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);
519 value
.Name
= rtl::OUString("Uri");
521 value
.Value
<<= m_aFTPURL
.ident(false,false);
522 value
.State
= PropertyState_DIRECT_VALUE
;
524 ucbhelper::cancelCommandExecution(
531 aRet
<<= UnsupportedDataSinkException(
533 static_cast< cppu::OWeakObject
* >(this),
535 ucbhelper::cancelCommandExecution(aRet
,Environment
);
538 else if(aOpenCommand
.Mode
== OpenMode::ALL
||
539 aOpenCommand
.Mode
== OpenMode::DOCUMENTS
||
540 aOpenCommand
.Mode
== OpenMode::FOLDERS
) {
541 std::vector
<FTPDirentry
> resvec
=
542 m_aFTPURL
.list(sal_Int16(aOpenCommand
.Mode
));
543 Reference
< XDynamicResultSet
> xSet
544 = new DynamicResultSet(
549 new ResultSetFactoryI(m_xContext
,
552 aOpenCommand
.Properties
,
553 aOpenCommand
.SortingInfo
,
557 else if(aOpenCommand
.Mode
==
558 OpenMode::DOCUMENT_SHARE_DENY_NONE
||
560 OpenMode::DOCUMENT_SHARE_DENY_WRITE
) {
561 // Unsupported OpenMode
562 aRet
<<= UnsupportedOpenModeException(
564 static_cast< cppu::OWeakObject
* >(this),
565 static_cast< sal_Int16
>(aOpenCommand
.Mode
));
566 ucbhelper::cancelCommandExecution(aRet
,Environment
);
569 aRet
<<= IllegalArgumentException(
570 rtl::OUString( "Unexpected OpenMode!" ),
571 static_cast< cppu::OWeakObject
* >(this),
574 ucbhelper::cancelCommandExecution(aRet
,Environment
);
576 } else if(aCommand
.Name
.compareToAscii("createNewContent") == 0) {
578 if (!(aCommand
.Argument
>>= aArg
)) {
579 ucbhelper::cancelCommandExecution(
581 IllegalArgumentException(
582 rtl::OUString( "Wrong argument type!" ),
583 static_cast< cppu::OWeakObject
* >(this),
588 aRet
<<= createNewContent(aArg
);
590 aRet
<<= UnsupportedCommandException(
592 static_cast< cppu::OWeakObject
* >(this));
593 ucbhelper::cancelCommandExecution(aRet
,Environment
);
597 } catch(const curl_exception
& e
) {
598 if(e
.code() == CURLE_COULDNT_CONNECT
)
599 action
= THROWINTERACTIVECONNECT
;
600 else if(e
.code() == CURLE_COULDNT_RESOLVE_HOST
)
601 action
= THROWRESOLVENAME
;
602 else if(e
.code() == CURLE_FTP_USER_PASSWORD_INCORRECT
||
603 e
.code() == CURLE_LOGIN_DENIED
||
604 e
.code() == CURLE_BAD_PASSWORD_ENTERED
||
605 e
.code() == CURLE_FTP_WEIRD_PASS_REPLY
)
606 action
= THROWAUTHENTICATIONREQUEST
;
607 else if(e
.code() == CURLE_FTP_ACCESS_DENIED
)
608 action
= THROWACCESSDENIED
;
609 else if(e
.code() == CURLE_FTP_QUOTE_ERROR
)
611 else if(e
.code() == CURLE_FTP_COULDNT_RETR_FILE
)
612 action
= THROWNOFILE
;
614 // nothing known about the cause of the error
615 action
= THROWGENERAL
;
619 #define FTP_FILE rtl::OUString( "application/vnd.sun.staroffice.ftp-file")
621 #define FTP_FOLDER rtl::OUString( "application/vnd.sun.staroffice.ftp-folder")
623 Sequence
<ContentInfo
> SAL_CALL
624 FTPContent::queryCreatableContentsInfo( )
625 throw (RuntimeException
)
627 return queryCreatableContentsInfo_Static();
631 Sequence
<ContentInfo
>
632 FTPContent::queryCreatableContentsInfo_Static( )
633 throw (RuntimeException
)
635 Sequence
< ContentInfo
> seq(2);
637 seq
[0].Type
= FTP_FILE
;
638 seq
[0].Attributes
= ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
639 | ContentInfoAttribute::KIND_DOCUMENT
;
640 Sequence
< Property
> props( 1 );
642 rtl::OUString("Title"),
644 getCppuType( static_cast< rtl::OUString
* >( 0 ) ),
645 PropertyAttribute::MAYBEVOID
646 | PropertyAttribute::BOUND
);
647 seq
[0].Properties
= props
;
650 seq
[1].Type
= FTP_FOLDER
;
651 seq
[1].Attributes
= ContentInfoAttribute::KIND_FOLDER
;
652 seq
[1].Properties
= props
;
657 Reference
<XContent
> SAL_CALL
658 FTPContent::createNewContent( const ContentInfo
& Info
)
659 throw (RuntimeException
)
661 if( Info
.Type
=="application/vnd.sun.staroffice.ftp-file" || Info
.Type
== "application/vnd.sun.staroffice.ftp-folder" )
662 return new FTPContent(m_xContext
,
666 return Reference
<XContent
>(0);
672 Reference
<XInterface
> SAL_CALL
673 FTPContent::getParent( )
674 throw (RuntimeException
)
676 Reference
<XContentIdentifier
>
677 xIdent(new FTPContentIdentifier(m_aFTPURL
.parent(false)));
678 Reference
<XContent
> xContent(m_xProvider
->queryContent(xIdent
));
679 return Reference
<XInterface
>(xContent
,UNO_QUERY
);
684 FTPContent::setParent(const Reference
<XInterface
>& /*Parent*/ )
685 throw (NoSupportException
,
688 throw NoSupportException();
693 rtl::OUString
FTPContent::getParentURL()
695 return m_aFTPURL
.parent();
704 InsertData(const Reference
<XInputStream
>& xInputStream
)
705 : m_xInputStream(xInputStream
) { }
706 virtual ~InsertData() {}
708 // returns the number of bytes actually read
709 virtual sal_Int32
read(sal_Int8
*dest
,sal_Int32 nBytesRequested
);
713 Reference
<XInputStream
> m_xInputStream
;
718 sal_Int32
InsertData::read(sal_Int8
*dest
,sal_Int32 nBytesRequested
)
722 if(m_xInputStream
.is()) {
723 Sequence
<sal_Int8
> seq(nBytesRequested
);
724 m
= m_xInputStream
->readBytes(seq
,nBytesRequested
);
725 memcpy(dest
,seq
.getConstArray(),m
);
731 void FTPContent::insert(const InsertCommandArgument
& aInsertCommand
,
732 const Reference
<XCommandEnvironment
>& Env
)
734 osl::MutexGuard
aGuard(m_aMutex
);
736 if(m_bInserted
&& !m_bTitleSet
) {
737 MissingPropertiesException excep
;
738 excep
.Properties
.realloc(1);
739 excep
.Properties
[0] = rtl::OUString("Title");
740 Any aAny
; aAny
<<= excep
;
741 ucbhelper::cancelCommandExecution(aAny
,Env
);
745 m_aInfo
.Type
== FTP_FILE
&&
746 !aInsertCommand
.Data
.is())
748 MissingInputStreamException excep
;
749 Any aAny
; aAny
<<= excep
;
750 ucbhelper::cancelCommandExecution(aAny
,Env
);
753 bool bReplace(aInsertCommand
.ReplaceExisting
);
757 if(m_aInfo
.Type
== FTP_FILE
) {
758 InsertData
data(aInsertCommand
.Data
);
759 m_aFTPURL
.insert(bReplace
,&data
);
760 } else if(m_aInfo
.Type
== FTP_FOLDER
)
761 m_aFTPURL
.mkdir(bReplace
);
762 } catch(const curl_exception
& e
) {
763 if(e
.code() == FILE_EXIST_DURING_INSERT
||
764 e
.code() == FOLDER_EXIST_DURING_INSERT
) {
765 // Deprecated, not used anymore:
766 NameClashException excep
;
767 excep
.Name
= m_aFTPURL
.child();
770 ucbhelper::cancelCommandExecution(aAny
,Env
);
771 } else if(e
.code() == FOLDER_MIGHT_EXIST_DURING_INSERT
||
772 e
.code() == FILE_MIGHT_EXIST_DURING_INSERT
) {
774 Reference
<XInteractionHandler
> xInt
;
776 xInt
= Env
->getInteractionHandler();
778 UnsupportedNameClashException excep
;
779 excep
.NameClash
= 0; //NameClash::ERROR;
784 ucbhelper::cancelCommandExecution(aAny
,Env
);
787 XInteractionRequestImpl
* p
=
788 new XInteractionRequestImpl(m_aFTPURL
.child());
789 Reference
<XInteractionRequest
> req(p
);
802 // May not be reached, because both mkdir and insert can throw curl-
810 Reference
< XRow
> FTPContent::getPropertyValues(
811 const Sequence
< Property
>& seqProp
,
812 const Reference
<XCommandEnvironment
>& /*environment*/
815 rtl::Reference
<ucbhelper::PropertyValueSet
> xRow
=
816 new ucbhelper::PropertyValueSet(m_xContext
);
818 FTPDirentry aDirEntry
= m_aFTPURL
.direntry();
820 for(sal_Int32 i
= 0; i
< seqProp
.getLength(); ++i
) {
821 const rtl::OUString
& Name
= seqProp
[i
].Name
;
822 if(Name
.compareToAscii("Title") == 0)
823 xRow
->appendString(seqProp
[i
],aDirEntry
.m_aName
);
824 else if(Name
.compareToAscii("CreatableContentsInfo") == 0)
825 xRow
->appendObject(seqProp
[i
],
826 makeAny(queryCreatableContentsInfo()));
827 else if(aDirEntry
.m_nMode
!= INETCOREFTP_FILEMODE_UNKNOWN
) {
828 if(Name
.compareToAscii("ContentType") == 0)
829 xRow
->appendString(seqProp
[i
],
830 aDirEntry
.m_nMode
&INETCOREFTP_FILEMODE_ISDIR
833 else if(Name
.compareToAscii("IsReadOnly") == 0)
834 xRow
->appendBoolean(seqProp
[i
],
836 & INETCOREFTP_FILEMODE_WRITE
839 else if(Name
.compareToAscii("IsDocument") == 0)
840 xRow
->appendBoolean(seqProp
[i
],
841 ! sal_Bool(aDirEntry
.m_nMode
&
842 INETCOREFTP_FILEMODE_ISDIR
));
843 else if(Name
.compareToAscii("IsFolder") == 0)
844 xRow
->appendBoolean(seqProp
[i
],
845 sal_Bool(aDirEntry
.m_nMode
&
846 INETCOREFTP_FILEMODE_ISDIR
));
847 else if(Name
.compareToAscii("Size") == 0)
848 xRow
->appendLong(seqProp
[i
],
850 else if(Name
.compareToAscii("DateCreated") == 0)
851 xRow
->appendTimestamp(seqProp
[i
],
854 xRow
->appendVoid(seqProp
[i
]);
856 xRow
->appendVoid(seqProp
[i
]);
859 return Reference
<XRow
>(xRow
.get());
864 Sequence
<Any
> FTPContent::setPropertyValues(
865 const Sequence
<PropertyValue
>& seqPropVal
)
867 Sequence
<Any
> ret(seqPropVal
.getLength());
868 Sequence
<PropertyChangeEvent
> evt
;
870 osl::MutexGuard
aGuard(m_aMutex
);
871 for(sal_Int32 i
= 0; i
< ret
.getLength(); ++i
) {
872 if ( seqPropVal
[i
].Name
== "Title" ) {
874 if(!(seqPropVal
[i
].Value
>>= Title
)) {
875 ret
[i
] <<= IllegalTypeException();
877 } else if(Title
.isEmpty()) {
878 ret
[i
] <<= IllegalArgumentException();
883 m_aFTPURL
.child(Title
);
885 new FTPContentIdentifier(m_aFTPURL
.ident(false,false));
889 rtl::OUString OldTitle
= m_aFTPURL
.ren(Title
);
891 evt
[0].PropertyName
=
892 rtl::OUString("Title");
893 evt
[0].Further
= false;
894 evt
[0].PropertyHandle
= -1;
895 evt
[0].OldValue
<<= OldTitle
;
896 evt
[0].NewValue
<<= Title
;
897 } catch(const curl_exception
&) {
898 InteractiveIOException excep
;
899 // any better possibility here?
900 // ( the error code is always CURLE_FTP_QUOTE_ERROR )
901 excep
.Code
= IOErrorCode_ACCESS_DENIED
;
905 Sequence
<Property
> props
=
906 getProperties(Reference
<XCommandEnvironment
>(0));
908 // either unknown or read-only
909 ret
[i
] <<= UnknownPropertyException();
910 for(sal_Int32 j
= 0; j
< props
.getLength(); ++j
)
911 if(props
[j
].Name
== seqPropVal
[i
].Name
) {
912 ret
[i
] <<= IllegalAccessException(
913 rtl::OUString( "Property is read-only!"),
914 //props[j].Attributes & PropertyAttribute::READONLY
915 // ? "Property is read-only!"
916 // : "Access denied!"),
917 static_cast< cppu::OWeakObject
* >( this ));
923 if(evt
.getLength()) {
925 notifyPropertiesChange(evt
);
926 exchange(new FTPContentIdentifier(m_aFTPURL
.ident(false,false)));
932 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */