1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 /**************************************************************************
32 **************************************************************************
34 *************************************************************************/
35 #include <com/sun/star/beans/PropertyAttribute.hpp>
37 #include "ftpdynresultset.hxx"
38 #include "ftpresultsetfactory.hxx"
39 #include "ftpresultsetI.hxx"
40 #include "ftpcontent.hxx"
41 #include "ftpcontentprovider.hxx"
42 #include "ftpdirp.hxx"
43 #include "ftpcontentidentifier.hxx"
44 #include "ftpcfunc.hxx"
45 #include "ftpstrcont.hxx"
46 #include "ftpintreq.hxx"
50 #include <rtl/memory.h>
52 #include <curl/easy.h>
53 #include <ucbhelper/cancelcommandexecution.hxx>
54 #include <ucbhelper/contentidentifier.hxx>
55 #include <ucbhelper/fd_inputstream.hxx>
56 #include <ucbhelper/propertyvalueset.hxx>
57 #include <ucbhelper/contentidentifier.hxx>
58 #include <ucbhelper/cancelcommandexecution.hxx>
59 #include <ucbhelper/simpleauthenticationrequest.hxx>
60 #include <com/sun/star/lang/IllegalAccessException.hpp>
61 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
62 #include <com/sun/star/beans/UnknownPropertyException.hpp>
63 #include <com/sun/star/beans/Property.hpp>
64 #include <com/sun/star/beans/PropertyValue.hpp>
65 #include <com/sun/star/ucb/XCommandInfo.hpp>
66 #include <com/sun/star/io/XActiveDataSink.hpp>
67 #include <com/sun/star/io/XOutputStream.hpp>
68 #include <com/sun/star/io/XActiveDataStreamer.hpp>
69 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
70 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
71 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
72 #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
73 #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
74 #include <com/sun/star/ucb/InteractiveIOException.hpp>
75 #include <com/sun/star/ucb/MissingPropertiesException.hpp>
76 #include <com/sun/star/ucb/MissingInputStreamException.hpp>
77 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
78 #include <com/sun/star/ucb/NameClashException.hpp>
79 #include <com/sun/star/ucb/OpenMode.hpp>
80 #include <com/sun/star/ucb/IOErrorCode.hpp>
83 using namespace com::sun::star::task
;
84 using namespace com::sun::star::container
;
85 using namespace com::sun::star::lang
;
86 using namespace com::sun::star::uno
;
87 using namespace com::sun::star::ucb
;
88 using namespace com::sun::star::beans
;
89 using namespace com::sun::star::io
;
90 using namespace com::sun::star::sdbc
;
94 //=========================================================================
95 //=========================================================================
97 // Content Implementation.
99 //=========================================================================
100 //=========================================================================
102 FTPContent::FTPContent( const Reference
< XMultiServiceFactory
>& rxSMgr
,
103 FTPContentProvider
* pProvider
,
104 const Reference
< XContentIdentifier
>& Identifier
,
105 const FTPURL
& aFTPURL
)
106 : ContentImplHelper(rxSMgr
,pProvider
,Identifier
),
116 FTPContent::FTPContent( const Reference
< XMultiServiceFactory
>& rxSMgr
,
117 FTPContentProvider
* pProvider
,
118 const Reference
< XContentIdentifier
>& Identifier
,
119 const ContentInfo
& Info
)
120 : ContentImplHelper(rxSMgr
,pProvider
,Identifier
),
122 m_aFTPURL(Identifier
->getContentIdentifier(),
132 //=========================================================================
134 FTPContent::~FTPContent()
139 //=========================================================================
141 // XInterface methods.
143 //=========================================================================
145 XINTERFACE_IMPL_6( FTPContent
,
153 //=========================================================================
155 // XTypeProvider methods.
157 //=========================================================================
159 XTYPEPROVIDER_IMPL_6( FTPContent
,
167 //=========================================================================
169 // XServiceInfo methods.
171 //=========================================================================
173 // needed, because the service shall not be creatable!!
174 #undef XSERVICEINFO_CREATE_INSTANCE_IMPL
175 #define XSERVICEINFO_CREATE_INSTANCE_IMPL( Class )
177 XSERVICEINFO_IMPL_1( FTPContent
,
178 rtl::OUString( "com.sun.star.comp.FTPContent"),
179 rtl::OUString( "com.sun.star.ucb.FTPContent"));
183 //=========================================================================
187 //=========================================================================
190 rtl::OUString SAL_CALL
FTPContent::getContentType()
191 throw( RuntimeException
)
193 return rtl::OUString(FTP_CONTENT_TYPE
);
197 //=========================================================================
199 // XCommandProcessor methods.
201 //=========================================================================
205 void SAL_CALL
FTPContent::abort( sal_Int32
/*CommandId*/ )
206 throw( RuntimeException
)
212 /***************************************************************************/
214 /* Internal implementation class. */
216 /***************************************************************************/
219 class ResultSetFactoryI
220 : public ResultSetFactory
224 ResultSetFactoryI(const Reference
<XMultiServiceFactory
>& xSMgr
,
225 const Reference
<XContentProvider
>& xProvider
,
227 const Sequence
<Property
>& seq
,
228 const Sequence
<NumberedSortingInfo
>& seqSort
,
229 const std::vector
<FTPDirentry
>& dirvec
)
231 m_xProvider(xProvider
),
232 m_nOpenMode(nOpenMode
),
239 virtual ResultSetBase
* createResultSet()
241 return new ResultSetI(m_xSMgr
,
251 Reference
< XMultiServiceFactory
> m_xSMgr
;
252 Reference
< XContentProvider
> m_xProvider
;
253 sal_Int32 m_nOpenMode
;
254 Sequence
< Property
> m_seq
;
255 Sequence
< NumberedSortingInfo
> m_seqSort
;
256 std::vector
<FTPDirentry
> m_dirvec
;
261 //=========================================================================
263 // XCommandProcessor methods.
265 //=========================================================================
267 enum ACTION
{ NOACTION
,
268 THROWAUTHENTICATIONREQUEST
,
270 THROWINTERACTIVECONNECT
,
278 Any SAL_CALL
FTPContent::execute(
279 const Command
& aCommand
,
280 sal_Int32
/*CommandId*/,
282 XCommandEnvironment
>& Environment
286 CommandAbortedException
,
290 ACTION
action(NOACTION
);
295 if(action
== THROWAUTHENTICATIONREQUEST
) {
296 // try to get a continuation first
297 rtl::OUString aRealm
,aPassword
,aAccount
;
298 m_pFCP
->forHost(m_aFTPURL
.host(),
300 m_aFTPURL
.username(),
303 rtl::Reference
<ucbhelper::SimpleAuthenticationRequest
>
304 p( new ucbhelper::SimpleAuthenticationRequest(
305 m_aFTPURL
.ident(false, false),
306 m_aFTPURL
.host(), // ServerName
307 ucbhelper::SimpleAuthenticationRequest::ENTITY_NA
,
309 ucbhelper::SimpleAuthenticationRequest
311 m_aFTPURL
.username(),
312 ucbhelper::SimpleAuthenticationRequest
316 Reference
<XInteractionHandler
> xInteractionHandler
;
318 xInteractionHandler
=
319 Environment
->getInteractionHandler();
321 if( xInteractionHandler
.is()) {
322 xInteractionHandler
->handle(p
.get());
324 Reference
<XInterface
> xSelection(
325 p
->getSelection().get());
327 if(Reference
<XInteractionRetry
>(
328 xSelection
,UNO_QUERY
).is())
330 else if(Reference
<XInteractionSupplyAuthentication
>(
331 xSelection
,UNO_QUERY
).is()) {
335 m_aFTPURL
.username(),
336 p
->getAuthenticationSupplier()->getPassword(),
341 aRet
= p
->getRequest();
344 // if(aCommand.Name.compareToAscii(
345 // "getPropertyValues") == 0 &&
346 // action != NOACTION) {
347 // // It is not allowed to throw if
348 // // command is getPropertyValues
349 // rtl::Reference<ucbhelper::PropertyValueSet> xRow =
350 // new ucbhelper::PropertyValueSet(m_xSMgr);
351 // Sequence<Property> Properties;
352 // aCommand.Argument >>= Properties;
353 // for(int i = 0; i < Properties.getLength(); ++i)
354 // xRow->appendVoid(Properties[i]);
355 // aRet <<= Reference<XRow>(xRow.get());
364 case THROWAUTHENTICATIONREQUEST
:
365 ucbhelper::cancelCommandExecution(
367 Reference
<XCommandEnvironment
>(0));
370 case THROWACCESSDENIED
:
372 Sequence
<Any
> seq(1);
374 value
.Name
= rtl::OUString("Uri");
376 value
.Value
<<= m_aFTPURL
.ident(false,false);
377 value
.State
= PropertyState_DIRECT_VALUE
;
379 ucbhelper::cancelCommandExecution(
380 IOErrorCode_ACCESS_DENIED
,
385 case THROWINTERACTIVECONNECT
:
387 InteractiveNetworkConnectException excep
;
388 excep
.Server
= m_aFTPURL
.host();
390 ucbhelper::cancelCommandExecution(
395 case THROWRESOLVENAME
:
397 InteractiveNetworkResolveNameException excep
;
398 excep
.Server
= m_aFTPURL
.host();
400 ucbhelper::cancelCommandExecution(
407 Sequence
<Any
> seq(1);
409 value
.Name
= rtl::OUString("Uri");
411 value
.Value
<<= m_aFTPURL
.ident(false,false);
412 value
.State
= PropertyState_DIRECT_VALUE
;
414 ucbhelper::cancelCommandExecution(
422 ucbhelper::cancelCommandExecution(
429 if(aCommand
.Name
.compareToAscii("getPropertyValues") == 0) {
430 Sequence
<Property
> Properties
;
431 if(!(aCommand
.Argument
>>= Properties
))
433 aRet
<<= IllegalArgumentException(
434 rtl::OUString( "Wrong argument type!" ),
435 static_cast< cppu::OWeakObject
* >(this),
437 ucbhelper::cancelCommandExecution(aRet
,Environment
);
440 aRet
<<= getPropertyValues(Properties
,Environment
);
442 else if(aCommand
.Name
.compareToAscii("setPropertyValues") == 0)
444 Sequence
<PropertyValue
> propertyValues
;
446 if( ! ( aCommand
.Argument
>>= propertyValues
) ) {
447 aRet
<<= IllegalArgumentException(
448 rtl::OUString( "Wrong argument type!" ),
449 static_cast< cppu::OWeakObject
* >(this),
451 ucbhelper::cancelCommandExecution(aRet
,Environment
);
454 aRet
<<= setPropertyValues(propertyValues
);
456 else if(aCommand
.Name
.compareToAscii("getCommandInfo") == 0) {
457 // Note: Implemented by base class.
458 aRet
<<= getCommandInfo(Environment
);
460 else if(aCommand
.Name
.compareToAscii("getPropertySetInfo") == 0) {
461 // Note: Implemented by base class.
462 aRet
<<= getPropertySetInfo(Environment
);
464 else if(aCommand
.Name
.compareToAscii( "insert" ) == 0)
466 InsertCommandArgument aInsertArgument
;
467 if ( ! ( aCommand
.Argument
>>= aInsertArgument
) ) {
468 aRet
<<= IllegalArgumentException(
469 rtl::OUString( "Wrong argument type!" ),
470 static_cast< cppu::OWeakObject
* >(this),
472 ucbhelper::cancelCommandExecution(aRet
,Environment
);
474 insert(aInsertArgument
,Environment
);
476 else if(aCommand
.Name
.compareToAscii("delete") == 0) {
480 else if(aCommand
.Name
.compareToAscii( "open" ) == 0) {
481 OpenCommandArgument2 aOpenCommand
;
482 if ( !( aCommand
.Argument
>>= aOpenCommand
) ) {
483 aRet
<<= IllegalArgumentException(
484 rtl::OUString( "Wrong argument type!" ),
485 static_cast< cppu::OWeakObject
* >(this),
488 ucbhelper::cancelCommandExecution(aRet
,Environment
);
491 if(aOpenCommand
.Mode
== OpenMode::DOCUMENT
) {
492 // Open as a document
493 Reference
<XActiveDataSink
>
494 xActiveDataSink(aOpenCommand
.Sink
,UNO_QUERY
);
495 Reference
< XOutputStream
>
496 xOutputStream(aOpenCommand
.Sink
,UNO_QUERY
);
498 if(xActiveDataSink
.is()) {
499 xActiveDataSink
->setInputStream(
500 new ucbhelper::FdInputStream(m_aFTPURL
.open()));
502 else if(xOutputStream
.is()) {
503 Reference
<XInputStream
> xStream(
504 new ucbhelper::FdInputStream(m_aFTPURL
.open()));
505 Sequence
<sal_Int8
> byte_seq(4096);
506 sal_Int32 n
= 1000; // value does not matter here
508 n
= xStream
->readBytes(byte_seq
,4096);
513 if(byte_seq
.getLength() != n
)
515 xOutputStream
->writeBytes(byte_seq
);
516 } catch(const NotConnectedException
&) {
518 } catch(const BufferSizeExceededException
&) {
520 } catch(const IOException
&) {
525 Sequence
<Any
> seq(1);
527 value
.Name
= rtl::OUString("Uri");
529 value
.Value
<<= m_aFTPURL
.ident(false,false);
530 value
.State
= PropertyState_DIRECT_VALUE
;
532 ucbhelper::cancelCommandExecution(
539 aRet
<<= UnsupportedDataSinkException(
541 static_cast< cppu::OWeakObject
* >(this),
543 ucbhelper::cancelCommandExecution(aRet
,Environment
);
546 else if(aOpenCommand
.Mode
== OpenMode::ALL
||
547 aOpenCommand
.Mode
== OpenMode::DOCUMENTS
||
548 aOpenCommand
.Mode
== OpenMode::FOLDERS
) {
549 std::vector
<FTPDirentry
> resvec
=
550 m_aFTPURL
.list(sal_Int16(aOpenCommand
.Mode
));
551 Reference
< XDynamicResultSet
> xSet
552 = new DynamicResultSet(
557 new ResultSetFactoryI(m_xSMgr
,
560 aOpenCommand
.Properties
,
561 aOpenCommand
.SortingInfo
,
565 else if(aOpenCommand
.Mode
==
566 OpenMode::DOCUMENT_SHARE_DENY_NONE
||
568 OpenMode::DOCUMENT_SHARE_DENY_WRITE
) {
569 // Unsupported OpenMode
570 aRet
<<= UnsupportedOpenModeException(
572 static_cast< cppu::OWeakObject
* >(this),
573 static_cast< sal_Int16
>(aOpenCommand
.Mode
));
574 ucbhelper::cancelCommandExecution(aRet
,Environment
);
577 aRet
<<= IllegalArgumentException(
578 rtl::OUString( "Unexpected OpenMode!" ),
579 static_cast< cppu::OWeakObject
* >(this),
582 ucbhelper::cancelCommandExecution(aRet
,Environment
);
584 } else if(aCommand
.Name
.compareToAscii("createNewContent") == 0) {
586 if (!(aCommand
.Argument
>>= aArg
)) {
587 ucbhelper::cancelCommandExecution(
589 IllegalArgumentException(
590 rtl::OUString( "Wrong argument type!" ),
591 static_cast< cppu::OWeakObject
* >(this),
596 aRet
<<= createNewContent(aArg
);
598 aRet
<<= UnsupportedCommandException(
600 static_cast< cppu::OWeakObject
* >(this));
601 ucbhelper::cancelCommandExecution(aRet
,Environment
);
605 } catch(const curl_exception
& e
) {
606 if(e
.code() == CURLE_COULDNT_CONNECT
)
607 action
= THROWINTERACTIVECONNECT
;
608 else if(e
.code() == CURLE_COULDNT_RESOLVE_HOST
)
609 action
= THROWRESOLVENAME
;
610 else if(e
.code() == CURLE_FTP_USER_PASSWORD_INCORRECT
||
611 e
.code() == CURLE_LOGIN_DENIED
||
612 e
.code() == CURLE_BAD_PASSWORD_ENTERED
||
613 e
.code() == CURLE_FTP_WEIRD_PASS_REPLY
)
614 action
= THROWAUTHENTICATIONREQUEST
;
615 else if(e
.code() == CURLE_FTP_ACCESS_DENIED
)
616 action
= THROWACCESSDENIED
;
617 else if(e
.code() == CURLE_FTP_QUOTE_ERROR
)
619 else if(e
.code() == CURLE_FTP_COULDNT_RETR_FILE
)
620 action
= THROWNOFILE
;
622 // nothing known about the cause of the error
623 action
= THROWGENERAL
;
627 #define FTP_FILE rtl::OUString( "application/vnd.sun.staroffice.ftp-file")
629 #define FTP_FOLDER rtl::OUString( "application/vnd.sun.staroffice.ftp-folder")
631 Sequence
<ContentInfo
> SAL_CALL
632 FTPContent::queryCreatableContentsInfo( )
633 throw (RuntimeException
)
635 return queryCreatableContentsInfo_Static();
639 Sequence
<ContentInfo
>
640 FTPContent::queryCreatableContentsInfo_Static( )
641 throw (RuntimeException
)
643 Sequence
< ContentInfo
> seq(2);
645 seq
[0].Type
= FTP_FILE
;
646 seq
[0].Attributes
= ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
647 | ContentInfoAttribute::KIND_DOCUMENT
;
648 Sequence
< Property
> props( 1 );
650 rtl::OUString("Title"),
652 getCppuType( static_cast< rtl::OUString
* >( 0 ) ),
653 PropertyAttribute::MAYBEVOID
654 | PropertyAttribute::BOUND
);
655 seq
[0].Properties
= props
;
658 seq
[1].Type
= FTP_FOLDER
;
659 seq
[1].Attributes
= ContentInfoAttribute::KIND_FOLDER
;
660 seq
[1].Properties
= props
;
665 Reference
<XContent
> SAL_CALL
666 FTPContent::createNewContent( const ContentInfo
& Info
)
667 throw (RuntimeException
)
669 if( Info
.Type
=="application/vnd.sun.staroffice.ftp-file" || Info
.Type
== "application/vnd.sun.staroffice.ftp-folder" )
670 return new FTPContent(m_xSMgr
,
674 return Reference
<XContent
>(0);
680 Reference
<XInterface
> SAL_CALL
681 FTPContent::getParent( )
682 throw (RuntimeException
)
684 Reference
<XContentIdentifier
>
685 xIdent(new FTPContentIdentifier(m_aFTPURL
.parent(false)));
686 Reference
<XContent
> xContent(m_xProvider
->queryContent(xIdent
));
687 return Reference
<XInterface
>(xContent
,UNO_QUERY
);
692 FTPContent::setParent(const Reference
<XInterface
>& /*Parent*/ )
693 throw (NoSupportException
,
696 throw NoSupportException();
701 rtl::OUString
FTPContent::getParentURL()
703 return m_aFTPURL
.parent();
712 InsertData(const Reference
<XInputStream
>& xInputStream
)
713 : m_xInputStream(xInputStream
) { }
714 virtual ~InsertData() {}
716 // returns the number of bytes actually read
717 virtual sal_Int32
read(sal_Int8
*dest
,sal_Int32 nBytesRequested
);
721 Reference
<XInputStream
> m_xInputStream
;
726 sal_Int32
InsertData::read(sal_Int8
*dest
,sal_Int32 nBytesRequested
)
730 if(m_xInputStream
.is()) {
731 Sequence
<sal_Int8
> seq(nBytesRequested
);
732 m
= m_xInputStream
->readBytes(seq
,nBytesRequested
);
733 rtl_copyMemory(dest
,seq
.getConstArray(),m
);
739 void FTPContent::insert(const InsertCommandArgument
& aInsertCommand
,
740 const Reference
<XCommandEnvironment
>& Env
)
742 osl::MutexGuard
aGuard(m_aMutex
);
744 if(m_bInserted
&& !m_bTitleSet
) {
745 MissingPropertiesException excep
;
746 excep
.Properties
.realloc(1);
747 excep
.Properties
[0] = rtl::OUString("Title");
748 Any aAny
; aAny
<<= excep
;
749 ucbhelper::cancelCommandExecution(aAny
,Env
);
753 m_aInfo
.Type
== FTP_FILE
&&
754 !aInsertCommand
.Data
.is())
756 MissingInputStreamException excep
;
757 Any aAny
; aAny
<<= excep
;
758 ucbhelper::cancelCommandExecution(aAny
,Env
);
761 bool bReplace(aInsertCommand
.ReplaceExisting
);
765 if(m_aInfo
.Type
== FTP_FILE
) {
766 InsertData
data(aInsertCommand
.Data
);
767 m_aFTPURL
.insert(bReplace
,&data
);
768 } else if(m_aInfo
.Type
== FTP_FOLDER
)
769 m_aFTPURL
.mkdir(bReplace
);
770 } catch(const curl_exception
& e
) {
771 if(e
.code() == FILE_EXIST_DURING_INSERT
||
772 e
.code() == FOLDER_EXIST_DURING_INSERT
) {
773 // Deprecated, not used anymore:
774 NameClashException excep
;
775 excep
.Name
= m_aFTPURL
.child();
778 ucbhelper::cancelCommandExecution(aAny
,Env
);
779 } else if(e
.code() == FOLDER_MIGHT_EXIST_DURING_INSERT
||
780 e
.code() == FILE_MIGHT_EXIST_DURING_INSERT
) {
782 Reference
<XInteractionHandler
> xInt
;
784 xInt
= Env
->getInteractionHandler();
786 UnsupportedNameClashException excep
;
787 excep
.NameClash
= 0; //NameClash::ERROR;
792 ucbhelper::cancelCommandExecution(aAny
,Env
);
795 XInteractionRequestImpl
* p
=
796 new XInteractionRequestImpl(m_aFTPURL
.child());
797 Reference
<XInteractionRequest
> req(p
);
810 // May not be reached, because both mkdir and insert can throw curl-
818 Reference
< XRow
> FTPContent::getPropertyValues(
819 const Sequence
< Property
>& seqProp
,
820 const Reference
<XCommandEnvironment
>& /*environment*/
823 rtl::Reference
<ucbhelper::PropertyValueSet
> xRow
=
824 new ucbhelper::PropertyValueSet(m_xSMgr
);
826 FTPDirentry aDirEntry
= m_aFTPURL
.direntry();
828 for(sal_Int32 i
= 0; i
< seqProp
.getLength(); ++i
) {
829 const rtl::OUString
& Name
= seqProp
[i
].Name
;
830 if(Name
.compareToAscii("Title") == 0)
831 xRow
->appendString(seqProp
[i
],aDirEntry
.m_aName
);
832 else if(Name
.compareToAscii("CreatableContentsInfo") == 0)
833 xRow
->appendObject(seqProp
[i
],
834 makeAny(queryCreatableContentsInfo()));
835 else if(aDirEntry
.m_nMode
!= INETCOREFTP_FILEMODE_UNKNOWN
) {
836 if(Name
.compareToAscii("ContentType") == 0)
837 xRow
->appendString(seqProp
[i
],
838 aDirEntry
.m_nMode
&INETCOREFTP_FILEMODE_ISDIR
841 else if(Name
.compareToAscii("IsReadOnly") == 0)
842 xRow
->appendBoolean(seqProp
[i
],
844 & INETCOREFTP_FILEMODE_WRITE
847 else if(Name
.compareToAscii("IsDocument") == 0)
848 xRow
->appendBoolean(seqProp
[i
],
849 ! sal_Bool(aDirEntry
.m_nMode
&
850 INETCOREFTP_FILEMODE_ISDIR
));
851 else if(Name
.compareToAscii("IsFolder") == 0)
852 xRow
->appendBoolean(seqProp
[i
],
853 sal_Bool(aDirEntry
.m_nMode
&
854 INETCOREFTP_FILEMODE_ISDIR
));
855 else if(Name
.compareToAscii("Size") == 0)
856 xRow
->appendLong(seqProp
[i
],
858 else if(Name
.compareToAscii("DateCreated") == 0)
859 xRow
->appendTimestamp(seqProp
[i
],
862 xRow
->appendVoid(seqProp
[i
]);
864 xRow
->appendVoid(seqProp
[i
]);
867 return Reference
<XRow
>(xRow
.get());
872 Sequence
<Any
> FTPContent::setPropertyValues(
873 const Sequence
<PropertyValue
>& seqPropVal
)
875 Sequence
<Any
> ret(seqPropVal
.getLength());
876 Sequence
<PropertyChangeEvent
> evt
;
878 osl::MutexGuard
aGuard(m_aMutex
);
879 for(sal_Int32 i
= 0; i
< ret
.getLength(); ++i
) {
880 if ( seqPropVal
[i
].Name
== "Title" ) {
882 if(!(seqPropVal
[i
].Value
>>= Title
)) {
883 ret
[i
] <<= IllegalTypeException();
885 } else if(Title
.isEmpty()) {
886 ret
[i
] <<= IllegalArgumentException();
891 m_aFTPURL
.child(Title
);
893 new FTPContentIdentifier(m_aFTPURL
.ident(false,false));
897 rtl::OUString OldTitle
= m_aFTPURL
.ren(Title
);
899 evt
[0].PropertyName
=
900 rtl::OUString("Title");
901 evt
[0].Further
= false;
902 evt
[0].PropertyHandle
= -1;
903 evt
[0].OldValue
<<= OldTitle
;
904 evt
[0].NewValue
<<= Title
;
905 } catch(const curl_exception
&) {
906 InteractiveIOException excep
;
907 // any better possibility here?
908 // ( the error code is always CURLE_FTP_QUOTE_ERROR )
909 excep
.Code
= IOErrorCode_ACCESS_DENIED
;
913 Sequence
<Property
> props
=
914 getProperties(Reference
<XCommandEnvironment
>(0));
916 // either unknown or read-only
917 ret
[i
] <<= UnknownPropertyException();
918 for(sal_Int32 j
= 0; j
< props
.getLength(); ++j
)
919 if(props
[j
].Name
== seqPropVal
[i
].Name
) {
920 ret
[i
] <<= IllegalAccessException(
921 rtl::OUString( "Property is read-only!"),
922 //props[j].Attributes & PropertyAttribute::READONLY
923 // ? "Property is read-only!"
924 // : "Access denied!"),
925 static_cast< cppu::OWeakObject
* >( this ));
931 if(evt
.getLength()) {
933 notifyPropertiesChange(evt
);
934 exchange(new FTPContentIdentifier(m_aFTPURL
.ident(false,false)));
940 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */