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/simpleauthenticationrequest.hxx>
50 #include <com/sun/star/lang/IllegalAccessException.hpp>
51 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
52 #include <com/sun/star/beans/UnknownPropertyException.hpp>
53 #include <com/sun/star/beans/Property.hpp>
54 #include <com/sun/star/beans/PropertyValue.hpp>
55 #include <com/sun/star/ucb/XCommandInfo.hpp>
56 #include <com/sun/star/io/XActiveDataSink.hpp>
57 #include <com/sun/star/io/XOutputStream.hpp>
58 #include <com/sun/star/io/XActiveDataStreamer.hpp>
59 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
60 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
61 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
62 #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
63 #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
64 #include <com/sun/star/ucb/InteractiveIOException.hpp>
65 #include <com/sun/star/ucb/MissingPropertiesException.hpp>
66 #include <com/sun/star/ucb/MissingInputStreamException.hpp>
67 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
68 #include <com/sun/star/ucb/NameClashException.hpp>
69 #include <com/sun/star/ucb/OpenMode.hpp>
70 #include <com/sun/star/ucb/IOErrorCode.hpp>
73 using namespace com::sun::star::task
;
74 using namespace com::sun::star::container
;
75 using namespace com::sun::star::lang
;
76 using namespace com::sun::star::uno
;
77 using namespace com::sun::star::ucb
;
78 using namespace com::sun::star::beans
;
79 using namespace com::sun::star::io
;
80 using namespace com::sun::star::sdbc
;
84 //=========================================================================
85 //=========================================================================
87 // Content Implementation.
89 //=========================================================================
90 //=========================================================================
92 FTPContent::FTPContent( const Reference
< XComponentContext
>& rxContext
,
93 FTPContentProvider
* pProvider
,
94 const Reference
< XContentIdentifier
>& Identifier
,
95 const FTPURL
& aFTPURL
)
96 : ContentImplHelper(rxContext
,pProvider
,Identifier
),
106 FTPContent::FTPContent( const Reference
< XComponentContext
>& rxContext
,
107 FTPContentProvider
* pProvider
,
108 const Reference
< XContentIdentifier
>& Identifier
,
109 const ContentInfo
& Info
)
110 : ContentImplHelper(rxContext
,pProvider
,Identifier
),
112 m_aFTPURL(Identifier
->getContentIdentifier(),
122 //=========================================================================
124 FTPContent::~FTPContent()
129 //=========================================================================
131 // XInterface methods.
133 //=========================================================================
135 XINTERFACE_IMPL_6( FTPContent
,
143 //=========================================================================
145 // XTypeProvider methods.
147 //=========================================================================
149 XTYPEPROVIDER_IMPL_6( FTPContent
,
157 //=========================================================================
159 // XServiceInfo methods.
161 //=========================================================================
163 // needed, because the service shall not be creatable!!
164 #undef XSERVICEINFO_CREATE_INSTANCE_IMPL
165 #define XSERVICEINFO_CREATE_INSTANCE_IMPL( Class )
167 XSERVICEINFO_IMPL_1( FTPContent
,
168 OUString( "com.sun.star.comp.FTPContent"),
169 OUString( "com.sun.star.ucb.FTPContent"));
173 //=========================================================================
177 //=========================================================================
180 OUString SAL_CALL
FTPContent::getContentType()
181 throw( RuntimeException
)
183 return OUString(FTP_CONTENT_TYPE
);
187 //=========================================================================
189 // XCommandProcessor methods.
191 //=========================================================================
195 void SAL_CALL
FTPContent::abort( sal_Int32
/*CommandId*/ )
196 throw( RuntimeException
)
202 /***************************************************************************/
204 /* Internal implementation class. */
206 /***************************************************************************/
209 class ResultSetFactoryI
210 : public ResultSetFactory
214 ResultSetFactoryI(const Reference
<XComponentContext
>& rxContext
,
215 const Reference
<XContentProvider
>& xProvider
,
217 const Sequence
<Property
>& seq
,
218 const Sequence
<NumberedSortingInfo
>& seqSort
,
219 const std::vector
<FTPDirentry
>& dirvec
)
220 : m_xContext(rxContext
),
221 m_xProvider(xProvider
),
222 m_nOpenMode(nOpenMode
),
229 virtual ResultSetBase
* createResultSet()
231 return new ResultSetI(m_xContext
,
241 Reference
< XComponentContext
> m_xContext
;
242 Reference
< XContentProvider
> m_xProvider
;
243 sal_Int32 m_nOpenMode
;
244 Sequence
< Property
> m_seq
;
245 Sequence
< NumberedSortingInfo
> m_seqSort
;
246 std::vector
<FTPDirentry
> m_dirvec
;
251 //=========================================================================
253 // XCommandProcessor methods.
255 //=========================================================================
257 enum ACTION
{ NOACTION
,
258 THROWAUTHENTICATIONREQUEST
,
260 THROWINTERACTIVECONNECT
,
268 Any SAL_CALL
FTPContent::execute(
269 const Command
& aCommand
,
270 sal_Int32
/*CommandId*/,
272 XCommandEnvironment
>& Environment
276 CommandAbortedException
,
280 ACTION
action(NOACTION
);
285 if(action
== THROWAUTHENTICATIONREQUEST
) {
286 // try to get a continuation first
287 OUString aRealm
,aPassword
,aAccount
;
288 m_pFCP
->forHost(m_aFTPURL
.host(),
290 m_aFTPURL
.username(),
293 rtl::Reference
<ucbhelper::SimpleAuthenticationRequest
>
294 p( new ucbhelper::SimpleAuthenticationRequest(
295 m_aFTPURL
.ident(false, false),
296 m_aFTPURL
.host(), // ServerName
297 ucbhelper::SimpleAuthenticationRequest::ENTITY_NA
,
299 ucbhelper::SimpleAuthenticationRequest
301 m_aFTPURL
.username(),
302 ucbhelper::SimpleAuthenticationRequest
306 Reference
<XInteractionHandler
> xInteractionHandler
;
308 xInteractionHandler
=
309 Environment
->getInteractionHandler();
311 if( xInteractionHandler
.is()) {
312 xInteractionHandler
->handle(p
.get());
314 Reference
<XInterface
> xSelection(
315 p
->getSelection().get());
317 if(Reference
<XInteractionRetry
>(
318 xSelection
,UNO_QUERY
).is())
320 else if(Reference
<XInteractionSupplyAuthentication
>(
321 xSelection
,UNO_QUERY
).is()) {
325 m_aFTPURL
.username(),
326 p
->getAuthenticationSupplier()->getPassword(),
331 aRet
= p
->getRequest();
334 // if(aCommand.Name.compareToAscii(
335 // "getPropertyValues") == 0 &&
336 // action != NOACTION) {
337 // // It is not allowed to throw if
338 // // command is getPropertyValues
339 // rtl::Reference<ucbhelper::PropertyValueSet> xRow =
340 // new ucbhelper::PropertyValueSet(m_xSMgr);
341 // Sequence<Property> Properties;
342 // aCommand.Argument >>= Properties;
343 // for(int i = 0; i < Properties.getLength(); ++i)
344 // xRow->appendVoid(Properties[i]);
345 // aRet <<= Reference<XRow>(xRow.get());
354 case THROWAUTHENTICATIONREQUEST
:
355 ucbhelper::cancelCommandExecution(
357 Reference
<XCommandEnvironment
>(0));
360 case THROWACCESSDENIED
:
362 Sequence
<Any
> seq(1);
364 value
.Name
= OUString("Uri");
366 value
.Value
<<= m_aFTPURL
.ident(false,false);
367 value
.State
= PropertyState_DIRECT_VALUE
;
369 ucbhelper::cancelCommandExecution(
370 IOErrorCode_ACCESS_DENIED
,
375 case THROWINTERACTIVECONNECT
:
377 InteractiveNetworkConnectException excep
;
378 excep
.Server
= m_aFTPURL
.host();
380 ucbhelper::cancelCommandExecution(
385 case THROWRESOLVENAME
:
387 InteractiveNetworkResolveNameException excep
;
388 excep
.Server
= m_aFTPURL
.host();
390 ucbhelper::cancelCommandExecution(
397 Sequence
<Any
> seq(1);
399 value
.Name
= OUString("Uri");
401 value
.Value
<<= m_aFTPURL
.ident(false,false);
402 value
.State
= PropertyState_DIRECT_VALUE
;
404 ucbhelper::cancelCommandExecution(
412 ucbhelper::cancelCommandExecution(
419 if(aCommand
.Name
.compareToAscii("getPropertyValues") == 0) {
420 Sequence
<Property
> Properties
;
421 if(!(aCommand
.Argument
>>= Properties
))
423 aRet
<<= IllegalArgumentException(
424 OUString( "Wrong argument type!" ),
425 static_cast< cppu::OWeakObject
* >(this),
427 ucbhelper::cancelCommandExecution(aRet
,Environment
);
430 aRet
<<= getPropertyValues(Properties
,Environment
);
432 else if(aCommand
.Name
.compareToAscii("setPropertyValues") == 0)
434 Sequence
<PropertyValue
> propertyValues
;
436 if( ! ( aCommand
.Argument
>>= propertyValues
) ) {
437 aRet
<<= IllegalArgumentException(
438 OUString( "Wrong argument type!" ),
439 static_cast< cppu::OWeakObject
* >(this),
441 ucbhelper::cancelCommandExecution(aRet
,Environment
);
444 aRet
<<= setPropertyValues(propertyValues
);
446 else if(aCommand
.Name
.compareToAscii("getCommandInfo") == 0) {
447 // Note: Implemented by base class.
448 aRet
<<= getCommandInfo(Environment
);
450 else if(aCommand
.Name
.compareToAscii("getPropertySetInfo") == 0) {
451 // Note: Implemented by base class.
452 aRet
<<= getPropertySetInfo(Environment
);
454 else if(aCommand
.Name
.compareToAscii( "insert" ) == 0)
456 InsertCommandArgument aInsertArgument
;
457 if ( ! ( aCommand
.Argument
>>= aInsertArgument
) ) {
458 aRet
<<= IllegalArgumentException(
459 OUString( "Wrong argument type!" ),
460 static_cast< cppu::OWeakObject
* >(this),
462 ucbhelper::cancelCommandExecution(aRet
,Environment
);
464 insert(aInsertArgument
,Environment
);
466 else if(aCommand
.Name
.compareToAscii("delete") == 0) {
470 else if(aCommand
.Name
.compareToAscii( "open" ) == 0) {
471 OpenCommandArgument2 aOpenCommand
;
472 if ( !( aCommand
.Argument
>>= aOpenCommand
) ) {
473 aRet
<<= IllegalArgumentException(
474 OUString( "Wrong argument type!" ),
475 static_cast< cppu::OWeakObject
* >(this),
478 ucbhelper::cancelCommandExecution(aRet
,Environment
);
481 if(aOpenCommand
.Mode
== OpenMode::DOCUMENT
) {
482 // Open as a document
483 Reference
<XActiveDataSink
>
484 xActiveDataSink(aOpenCommand
.Sink
,UNO_QUERY
);
485 Reference
< XOutputStream
>
486 xOutputStream(aOpenCommand
.Sink
,UNO_QUERY
);
488 if(xActiveDataSink
.is()) {
489 xActiveDataSink
->setInputStream(
490 new ucbhelper::FdInputStream(m_aFTPURL
.open()));
492 else if(xOutputStream
.is()) {
493 Reference
<XInputStream
> xStream(
494 new ucbhelper::FdInputStream(m_aFTPURL
.open()));
495 Sequence
<sal_Int8
> byte_seq(4096);
496 sal_Int32 n
= 1000; // value does not matter here
498 n
= xStream
->readBytes(byte_seq
,4096);
503 if(byte_seq
.getLength() != n
)
505 xOutputStream
->writeBytes(byte_seq
);
506 } catch(const NotConnectedException
&) {
508 } catch(const BufferSizeExceededException
&) {
510 } catch(const IOException
&) {
515 Sequence
<Any
> seq(1);
517 value
.Name
= OUString("Uri");
519 value
.Value
<<= m_aFTPURL
.ident(false,false);
520 value
.State
= PropertyState_DIRECT_VALUE
;
522 ucbhelper::cancelCommandExecution(
529 aRet
<<= UnsupportedDataSinkException(
531 static_cast< cppu::OWeakObject
* >(this),
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_xContext
,
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(
562 static_cast< cppu::OWeakObject
* >(this),
563 static_cast< sal_Int16
>(aOpenCommand
.Mode
));
564 ucbhelper::cancelCommandExecution(aRet
,Environment
);
567 aRet
<<= IllegalArgumentException(
568 OUString( "Unexpected OpenMode!" ),
569 static_cast< cppu::OWeakObject
* >(this),
572 ucbhelper::cancelCommandExecution(aRet
,Environment
);
574 } else if(aCommand
.Name
.compareToAscii("createNewContent") == 0) {
576 if (!(aCommand
.Argument
>>= aArg
)) {
577 ucbhelper::cancelCommandExecution(
579 IllegalArgumentException(
580 OUString( "Wrong argument type!" ),
581 static_cast< cppu::OWeakObject
* >(this),
586 aRet
<<= createNewContent(aArg
);
588 aRet
<<= UnsupportedCommandException(
590 static_cast< cppu::OWeakObject
* >(this));
591 ucbhelper::cancelCommandExecution(aRet
,Environment
);
595 } catch(const curl_exception
& e
) {
596 if(e
.code() == CURLE_COULDNT_CONNECT
)
597 action
= THROWINTERACTIVECONNECT
;
598 else if(e
.code() == CURLE_COULDNT_RESOLVE_HOST
)
599 action
= THROWRESOLVENAME
;
600 else if(e
.code() == CURLE_FTP_USER_PASSWORD_INCORRECT
||
601 e
.code() == CURLE_LOGIN_DENIED
||
602 e
.code() == CURLE_BAD_PASSWORD_ENTERED
||
603 e
.code() == CURLE_FTP_WEIRD_PASS_REPLY
)
604 action
= THROWAUTHENTICATIONREQUEST
;
605 else if(e
.code() == CURLE_FTP_ACCESS_DENIED
)
606 action
= THROWACCESSDENIED
;
607 else if(e
.code() == CURLE_FTP_QUOTE_ERROR
)
609 else if(e
.code() == CURLE_FTP_COULDNT_RETR_FILE
)
610 action
= THROWNOFILE
;
612 // nothing known about the cause of the error
613 action
= THROWGENERAL
;
617 #define FTP_FILE OUString( "application/vnd.sun.staroffice.ftp-file")
619 #define FTP_FOLDER OUString( "application/vnd.sun.staroffice.ftp-folder")
621 Sequence
<ContentInfo
> SAL_CALL
622 FTPContent::queryCreatableContentsInfo( )
623 throw (RuntimeException
)
625 return queryCreatableContentsInfo_Static();
629 Sequence
<ContentInfo
>
630 FTPContent::queryCreatableContentsInfo_Static( )
631 throw (RuntimeException
)
633 Sequence
< ContentInfo
> seq(2);
635 seq
[0].Type
= FTP_FILE
;
636 seq
[0].Attributes
= ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
637 | ContentInfoAttribute::KIND_DOCUMENT
;
638 Sequence
< Property
> props( 1 );
642 getCppuType( static_cast< OUString
* >( 0 ) ),
643 PropertyAttribute::MAYBEVOID
644 | PropertyAttribute::BOUND
);
645 seq
[0].Properties
= props
;
648 seq
[1].Type
= FTP_FOLDER
;
649 seq
[1].Attributes
= ContentInfoAttribute::KIND_FOLDER
;
650 seq
[1].Properties
= props
;
655 Reference
<XContent
> SAL_CALL
656 FTPContent::createNewContent( const ContentInfo
& Info
)
657 throw (RuntimeException
)
659 if( Info
.Type
=="application/vnd.sun.staroffice.ftp-file" || Info
.Type
== "application/vnd.sun.staroffice.ftp-folder" )
660 return new FTPContent(m_xContext
,
664 return Reference
<XContent
>(0);
670 Reference
<XInterface
> SAL_CALL
671 FTPContent::getParent( )
672 throw (RuntimeException
)
674 Reference
<XContentIdentifier
>
675 xIdent(new FTPContentIdentifier(m_aFTPURL
.parent(false)));
676 Reference
<XContent
> xContent(m_xProvider
->queryContent(xIdent
));
677 return Reference
<XInterface
>(xContent
,UNO_QUERY
);
682 FTPContent::setParent(const Reference
<XInterface
>& /*Parent*/ )
683 throw (NoSupportException
,
686 throw NoSupportException();
691 OUString
FTPContent::getParentURL()
693 return m_aFTPURL
.parent();
702 InsertData(const Reference
<XInputStream
>& xInputStream
)
703 : m_xInputStream(xInputStream
) { }
704 virtual ~InsertData() {}
706 // returns the number of bytes actually read
707 virtual sal_Int32
read(sal_Int8
*dest
,sal_Int32 nBytesRequested
);
711 Reference
<XInputStream
> m_xInputStream
;
716 sal_Int32
InsertData::read(sal_Int8
*dest
,sal_Int32 nBytesRequested
)
720 if(m_xInputStream
.is()) {
721 Sequence
<sal_Int8
> seq(nBytesRequested
);
722 m
= m_xInputStream
->readBytes(seq
,nBytesRequested
);
723 memcpy(dest
,seq
.getConstArray(),m
);
729 void FTPContent::insert(const InsertCommandArgument
& aInsertCommand
,
730 const Reference
<XCommandEnvironment
>& Env
)
732 osl::MutexGuard
aGuard(m_aMutex
);
734 if(m_bInserted
&& !m_bTitleSet
) {
735 MissingPropertiesException excep
;
736 excep
.Properties
.realloc(1);
737 excep
.Properties
[0] = OUString("Title");
738 Any aAny
; aAny
<<= excep
;
739 ucbhelper::cancelCommandExecution(aAny
,Env
);
743 m_aInfo
.Type
== FTP_FILE
&&
744 !aInsertCommand
.Data
.is())
746 MissingInputStreamException excep
;
747 Any aAny
; aAny
<<= excep
;
748 ucbhelper::cancelCommandExecution(aAny
,Env
);
751 bool bReplace(aInsertCommand
.ReplaceExisting
);
755 if(m_aInfo
.Type
== FTP_FILE
) {
756 InsertData
data(aInsertCommand
.Data
);
757 m_aFTPURL
.insert(bReplace
,&data
);
758 } else if(m_aInfo
.Type
== FTP_FOLDER
)
759 m_aFTPURL
.mkdir(bReplace
);
760 } catch(const curl_exception
& e
) {
761 if(e
.code() == FILE_EXIST_DURING_INSERT
||
762 e
.code() == FOLDER_EXIST_DURING_INSERT
) {
763 // Deprecated, not used anymore:
764 NameClashException excep
;
765 excep
.Name
= m_aFTPURL
.child();
768 ucbhelper::cancelCommandExecution(aAny
,Env
);
769 } else if(e
.code() == FOLDER_MIGHT_EXIST_DURING_INSERT
||
770 e
.code() == FILE_MIGHT_EXIST_DURING_INSERT
) {
772 Reference
<XInteractionHandler
> xInt
;
774 xInt
= Env
->getInteractionHandler();
776 UnsupportedNameClashException excep
;
777 excep
.NameClash
= 0; //NameClash::ERROR;
782 ucbhelper::cancelCommandExecution(aAny
,Env
);
785 XInteractionRequestImpl
* p
=
786 new XInteractionRequestImpl(m_aFTPURL
.child());
787 Reference
<XInteractionRequest
> req(p
);
800 // May not be reached, because both mkdir and insert can throw curl-
808 Reference
< XRow
> FTPContent::getPropertyValues(
809 const Sequence
< Property
>& seqProp
,
810 const Reference
<XCommandEnvironment
>& /*environment*/
813 rtl::Reference
<ucbhelper::PropertyValueSet
> xRow
=
814 new ucbhelper::PropertyValueSet(m_xContext
);
816 FTPDirentry aDirEntry
= m_aFTPURL
.direntry();
818 for(sal_Int32 i
= 0; i
< seqProp
.getLength(); ++i
) {
819 const OUString
& Name
= seqProp
[i
].Name
;
820 if(Name
.compareToAscii("Title") == 0)
821 xRow
->appendString(seqProp
[i
],aDirEntry
.m_aName
);
822 else if(Name
.compareToAscii("CreatableContentsInfo") == 0)
823 xRow
->appendObject(seqProp
[i
],
824 makeAny(queryCreatableContentsInfo()));
825 else if(aDirEntry
.m_nMode
!= INETCOREFTP_FILEMODE_UNKNOWN
) {
826 if(Name
.compareToAscii("ContentType") == 0)
827 xRow
->appendString(seqProp
[i
],
828 aDirEntry
.m_nMode
&INETCOREFTP_FILEMODE_ISDIR
831 else if(Name
.compareToAscii("IsReadOnly") == 0)
832 xRow
->appendBoolean(seqProp
[i
],
834 & INETCOREFTP_FILEMODE_WRITE
837 else if(Name
.compareToAscii("IsDocument") == 0)
838 xRow
->appendBoolean(seqProp
[i
],
839 ! sal_Bool(aDirEntry
.m_nMode
&
840 INETCOREFTP_FILEMODE_ISDIR
));
841 else if(Name
.compareToAscii("IsFolder") == 0)
842 xRow
->appendBoolean(seqProp
[i
],
843 sal_Bool(aDirEntry
.m_nMode
&
844 INETCOREFTP_FILEMODE_ISDIR
));
845 else if(Name
.compareToAscii("Size") == 0)
846 xRow
->appendLong(seqProp
[i
],
848 else if(Name
.compareToAscii("DateCreated") == 0)
849 xRow
->appendTimestamp(seqProp
[i
],
852 xRow
->appendVoid(seqProp
[i
]);
854 xRow
->appendVoid(seqProp
[i
]);
857 return Reference
<XRow
>(xRow
.get());
862 Sequence
<Any
> FTPContent::setPropertyValues(
863 const Sequence
<PropertyValue
>& seqPropVal
)
865 Sequence
<Any
> ret(seqPropVal
.getLength());
866 Sequence
<PropertyChangeEvent
> evt
;
868 osl::MutexGuard
aGuard(m_aMutex
);
869 for(sal_Int32 i
= 0; i
< ret
.getLength(); ++i
) {
870 if ( seqPropVal
[i
].Name
== "Title" ) {
872 if(!(seqPropVal
[i
].Value
>>= Title
)) {
873 ret
[i
] <<= IllegalTypeException();
875 } else if(Title
.isEmpty()) {
876 ret
[i
] <<= IllegalArgumentException();
881 m_aFTPURL
.child(Title
);
883 new FTPContentIdentifier(m_aFTPURL
.ident(false,false));
887 OUString OldTitle
= m_aFTPURL
.ren(Title
);
889 evt
[0].PropertyName
=
891 evt
[0].Further
= false;
892 evt
[0].PropertyHandle
= -1;
893 evt
[0].OldValue
<<= OldTitle
;
894 evt
[0].NewValue
<<= Title
;
895 } catch(const curl_exception
&) {
896 InteractiveIOException excep
;
897 // any better possibility here?
898 // ( the error code is always CURLE_FTP_QUOTE_ERROR )
899 excep
.Code
= IOErrorCode_ACCESS_DENIED
;
903 Sequence
<Property
> props
=
904 getProperties(Reference
<XCommandEnvironment
>(0));
906 // either unknown or read-only
907 ret
[i
] <<= UnknownPropertyException();
908 for(sal_Int32 j
= 0; j
< props
.getLength(); ++j
)
909 if(props
[j
].Name
== seqPropVal
[i
].Name
) {
910 ret
[i
] <<= IllegalAccessException(
911 OUString( "Property is read-only!"),
912 //props[j].Attributes & PropertyAttribute::READONLY
913 // ? "Property is read-only!"
914 // : "Access denied!"),
915 static_cast< cppu::OWeakObject
* >( this ));
921 if(evt
.getLength()) {
923 notifyPropertiesChange(evt
);
924 exchange(new FTPContentIdentifier(m_aFTPURL
.ident(false,false)));
930 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */