fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / ucb / source / ucp / ftp / ftpcontent.cxx
blob59c889a03960cc161d5f1c8013b3410d29edf27b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 /**************************************************************************
22 TODO
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"
39 #include <memory>
40 #include <vector>
41 #include <string.h>
42 #include "curl.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>
72 using namespace ftp;
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;
83 // Content Implementation.
85 FTPContent::FTPContent( const Reference< XComponentContext >& rxContext,
86 FTPContentProvider* pProvider,
87 const Reference< XContentIdentifier >& Identifier,
88 const FTPURL& aFTPURL)
89 : ContentImplHelper(rxContext,pProvider,Identifier)
90 , m_pFCP(pProvider)
91 , m_aFTPURL(aFTPURL)
92 , m_bInserted(false)
93 , m_bTitleSet(false)
97 FTPContent::FTPContent( const Reference< XComponentContext >& rxContext,
98 FTPContentProvider* pProvider,
99 const Reference< XContentIdentifier >& Identifier,
100 const ContentInfo& Info)
101 : ContentImplHelper(rxContext,pProvider,Identifier)
102 , m_pFCP(pProvider)
103 , m_aFTPURL(Identifier->getContentIdentifier(), pProvider)
104 , m_bInserted(true)
105 , m_bTitleSet(false)
106 , m_aInfo(Info)
110 FTPContent::~FTPContent()
114 // XInterface methods.
116 void SAL_CALL FTPContent::acquire()
117 throw()
119 OWeakObject::acquire();
122 void SAL_CALL FTPContent::release()
123 throw()
125 OWeakObject::release();
128 css::uno::Any SAL_CALL FTPContent::queryInterface( const css::uno::Type & rType )
129 throw( css::uno::RuntimeException, std::exception )
131 css::uno::Any aRet = cppu::queryInterface( rType,
132 (static_cast< XTypeProvider* >(this)),
133 (static_cast< XServiceInfo* >(this)),
134 (static_cast< XContent* >(this)),
135 (static_cast< XCommandProcessor* >(this)),
136 (static_cast< XContentCreator* >(this)),
137 (static_cast< XChild* >(this))
139 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
142 // XTypeProvider methods.
144 css::uno::Sequence< sal_Int8 > SAL_CALL FTPContent::getImplementationId()
145 throw( css::uno::RuntimeException,
146 std::exception )
148 return css::uno::Sequence<sal_Int8>();
151 css::uno::Sequence< css::uno::Type > SAL_CALL FTPContent::getTypes()
152 throw( css::uno::RuntimeException,
153 std::exception )
155 static cppu::OTypeCollection* pCollection = NULL;
156 if ( !pCollection )
158 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
159 if ( !pCollection )
161 static cppu::OTypeCollection collection(
162 cppu::UnoType<XTypeProvider>::get(),
163 cppu::UnoType<XServiceInfo>::get(),
164 cppu::UnoType<XContent>::get(),
165 cppu::UnoType<XCommandProcessor>::get(),
166 cppu::UnoType<XContentCreator>::get(),
167 cppu::UnoType<XChild>::get()
169 pCollection = &collection;
172 return (*pCollection).getTypes();
177 // XServiceInfo methods.
179 OUString SAL_CALL FTPContent::getImplementationName()
180 throw( css::uno::RuntimeException, std::exception )
182 return getImplementationName_Static();
185 OUString FTPContent::getImplementationName_Static()
187 return OUString( "com.sun.star.comp.FTPContent");
190 sal_Bool SAL_CALL FTPContent::supportsService( const OUString& ServiceName )
191 throw( css::uno::RuntimeException, std::exception )
193 return cppu::supportsService( this, ServiceName );
196 css::uno::Sequence< OUString > SAL_CALL FTPContent::getSupportedServiceNames()
197 throw( css::uno::RuntimeException, std::exception )
199 return getSupportedServiceNames_Static();
202 css::uno::Sequence< OUString > FTPContent::getSupportedServiceNames_Static()
204 css::uno::Sequence< OUString > aSNS( 1 );
205 aSNS.getArray()[ 0 ] = "com.sun.star.ucb.FTPContent";
206 return aSNS;
213 // XContent methods.
215 // virtual
216 OUString SAL_CALL FTPContent::getContentType()
217 throw( RuntimeException, std::exception )
219 return OUString(FTP_CONTENT_TYPE);
222 // XCommandProcessor methods.
224 //virtual
225 void SAL_CALL FTPContent::abort( sal_Int32 /*CommandId*/ )
226 throw( RuntimeException, std::exception )
230 /***************************************************************************/
231 /* */
232 /* Internal implementation class. */
233 /* */
234 /***************************************************************************/
236 class ResultSetFactoryI : public ResultSetFactory
238 public:
240 ResultSetFactoryI(const Reference<XComponentContext >& rxContext,
241 const Reference<XContentProvider >& xProvider,
242 sal_Int32 nOpenMode,
243 const Sequence<Property>& seq,
244 const Sequence<NumberedSortingInfo>& seqSort,
245 const std::vector<FTPDirentry>& dirvec)
246 : m_xContext(rxContext),
247 m_xProvider(xProvider),
248 m_nOpenMode(nOpenMode),
249 m_seq(seq),
250 m_seqSort(seqSort),
251 m_dirvec(dirvec)
255 virtual ResultSetBase* createResultSet() SAL_OVERRIDE
257 return new ResultSetI(m_xContext,
258 m_xProvider,
259 m_nOpenMode,
260 m_seq,
261 m_seqSort,
262 m_dirvec);
265 public:
267 Reference< XComponentContext > m_xContext;
268 Reference< XContentProvider > m_xProvider;
269 sal_Int32 m_nOpenMode;
270 Sequence< Property > m_seq;
271 Sequence< NumberedSortingInfo > m_seqSort;
272 std::vector<FTPDirentry> m_dirvec;
275 // XCommandProcessor methods.
277 enum ACTION { NOACTION,
278 THROWAUTHENTICATIONREQUEST,
279 THROWACCESSDENIED,
280 THROWINTERACTIVECONNECT,
281 THROWRESOLVENAME,
282 THROWQUOTE,
283 THROWNOFILE,
284 THROWGENERAL };
286 // virtual
287 Any SAL_CALL FTPContent::execute( const Command& aCommand,
288 sal_Int32 /*CommandId*/,
289 const Reference<
290 XCommandEnvironment >& Environment)
291 throw( Exception,
292 CommandAbortedException,
293 RuntimeException,
294 std::exception)
296 ACTION action(NOACTION);
297 Any aRet;
299 while(true)
303 if(action == THROWAUTHENTICATIONREQUEST)
305 // try to get a continuation first
306 OUString aRealm,aPassword,aAccount;
307 m_pFCP->forHost(m_aFTPURL.host(),
308 m_aFTPURL.port(),
309 m_aFTPURL.username(),
310 aPassword,
311 aAccount);
312 rtl::Reference<ucbhelper::SimpleAuthenticationRequest>
313 p( new ucbhelper::SimpleAuthenticationRequest(
314 m_aFTPURL.ident(false, false),
315 m_aFTPURL.host(), // ServerName
316 ucbhelper::SimpleAuthenticationRequest::ENTITY_NA,
317 aRealm,
318 ucbhelper::SimpleAuthenticationRequest
319 ::ENTITY_FIXED,
320 m_aFTPURL.username(),
321 ucbhelper::SimpleAuthenticationRequest
322 ::ENTITY_MODIFY,
323 aPassword));
325 Reference<XInteractionHandler> xInteractionHandler;
326 if(Environment.is())
327 xInteractionHandler =
328 Environment->getInteractionHandler();
330 if( xInteractionHandler.is()) {
331 xInteractionHandler->handle(p.get());
333 Reference<XInterface> xSelection(
334 p->getSelection().get());
336 if(Reference<XInteractionRetry>(
337 xSelection,UNO_QUERY).is())
338 action = NOACTION;
339 else if(Reference<XInteractionSupplyAuthentication>(
340 xSelection,UNO_QUERY).is()) {
341 m_pFCP->setHost(
342 m_aFTPURL.host(),
343 m_aFTPURL.port(),
344 m_aFTPURL.username(),
345 p->getAuthenticationSupplier()->getPassword(),
346 aAccount);
347 action = NOACTION;
350 aRet = p->getRequest();
353 // if(aCommand.Name.equalsAscii(
354 // "getPropertyValues") &&
355 // action != NOACTION) {
356 // // It is not allowed to throw if
357 // // command is getPropertyValues
358 // rtl::Reference<ucbhelper::PropertyValueSet> xRow =
359 // new ucbhelper::PropertyValueSet(m_xSMgr);
360 // Sequence<Property> Properties;
361 // aCommand.Argument >>= Properties;
362 // for(int i = 0; i < Properties.getLength(); ++i)
363 // xRow->appendVoid(Properties[i]);
364 // aRet <<= Reference<XRow>(xRow.get());
365 // return aRet;
366 // }
368 switch (action)
370 case NOACTION:
371 break;
373 case THROWAUTHENTICATIONREQUEST:
374 ucbhelper::cancelCommandExecution(
375 aRet,
376 Reference<XCommandEnvironment>(0));
377 break;
379 case THROWACCESSDENIED:
381 Sequence<Any> seq(1);
382 PropertyValue value;
383 value.Name = "Uri";
384 value.Handle = -1;
385 value.Value <<= m_aFTPURL.ident(false,false);
386 value.State = PropertyState_DIRECT_VALUE;
387 seq[0] <<= value;
388 ucbhelper::cancelCommandExecution(
389 IOErrorCode_ACCESS_DENIED,
390 seq,
391 Environment);
392 break;
394 case THROWINTERACTIVECONNECT:
396 InteractiveNetworkConnectException excep;
397 excep.Server = m_aFTPURL.host();
398 aRet <<= excep;
399 ucbhelper::cancelCommandExecution(
400 aRet,
401 Environment);
402 break;
404 case THROWRESOLVENAME:
406 InteractiveNetworkResolveNameException excep;
407 excep.Server = m_aFTPURL.host();
408 aRet <<= excep;
409 ucbhelper::cancelCommandExecution(
410 aRet,
411 Environment);
412 break;
414 case THROWNOFILE:
416 Sequence<Any> seq(1);
417 PropertyValue value;
418 value.Name = "Uri";
419 value.Handle = -1;
420 value.Value <<= m_aFTPURL.ident(false,false);
421 value.State = PropertyState_DIRECT_VALUE;
422 seq[0] <<= value;
423 ucbhelper::cancelCommandExecution(
424 IOErrorCode_NO_FILE,
425 seq,
426 Environment);
427 break;
429 case THROWQUOTE:
430 case THROWGENERAL:
431 ucbhelper::cancelCommandExecution(
432 IOErrorCode_GENERAL,
433 Sequence<Any>(0),
434 Environment);
435 break;
438 if(aCommand.Name == "getPropertyValues") {
439 Sequence<Property> Properties;
440 if(!(aCommand.Argument >>= Properties))
442 aRet <<= IllegalArgumentException(
443 OUString( "Wrong argument type!" ),
444 static_cast< cppu::OWeakObject * >(this),
445 -1);
446 ucbhelper::cancelCommandExecution(aRet,Environment);
449 aRet <<= getPropertyValues(Properties,Environment);
451 else if(aCommand.Name == "setPropertyValues")
453 Sequence<PropertyValue> propertyValues;
455 if( ! ( aCommand.Argument >>= propertyValues ) ) {
456 aRet <<= IllegalArgumentException(
457 OUString( "Wrong argument type!" ),
458 static_cast< cppu::OWeakObject * >(this),
459 -1);
460 ucbhelper::cancelCommandExecution(aRet,Environment);
463 aRet <<= setPropertyValues(propertyValues);
465 else if(aCommand.Name == "getCommandInfo") {
466 // Note: Implemented by base class.
467 aRet <<= getCommandInfo(Environment);
469 else if(aCommand.Name == "getPropertySetInfo") {
470 // Note: Implemented by base class.
471 aRet <<= getPropertySetInfo(Environment);
473 else if(aCommand.Name == "insert")
475 InsertCommandArgument aInsertArgument;
476 if ( ! ( aCommand.Argument >>= aInsertArgument ) ) {
477 aRet <<= IllegalArgumentException(
478 OUString( "Wrong argument type!" ),
479 static_cast< cppu::OWeakObject * >(this),
480 -1);
481 ucbhelper::cancelCommandExecution(aRet,Environment);
483 insert(aInsertArgument,Environment);
485 else if(aCommand.Name == "delete") {
486 m_aFTPURL.del();
487 deleted();
489 else if(aCommand.Name == "open") {
490 OpenCommandArgument2 aOpenCommand;
491 if ( !( aCommand.Argument >>= aOpenCommand ) ) {
492 aRet <<= IllegalArgumentException(
493 OUString( "Wrong argument type!" ),
494 static_cast< cppu::OWeakObject * >(this),
495 -1);
497 ucbhelper::cancelCommandExecution(aRet,Environment);
500 if(aOpenCommand.Mode == OpenMode::DOCUMENT) {
501 // Open as a document
502 Reference<XActiveDataSink>
503 xActiveDataSink(aOpenCommand.Sink,UNO_QUERY);
504 Reference< XOutputStream >
505 xOutputStream(aOpenCommand.Sink,UNO_QUERY);
507 if(xActiveDataSink.is()) {
508 xActiveDataSink->setInputStream(
509 new ucbhelper::FdInputStream(m_aFTPURL.open()));
511 else if(xOutputStream.is()) {
512 Reference<XInputStream> xStream(
513 new ucbhelper::FdInputStream(m_aFTPURL.open()));
514 Sequence<sal_Int8> byte_seq(4096);
515 sal_Int32 n = 1000; // value does not matter here
516 for (;;) {
517 n = xStream->readBytes(byte_seq,4096);
518 if (n == 0) {
519 break;
521 try {
522 if(byte_seq.getLength() != n)
523 byte_seq.realloc(n);
524 xOutputStream->writeBytes(byte_seq);
525 } catch(const NotConnectedException&) {
527 } catch(const BufferSizeExceededException&) {
529 } catch(const IOException&) {
533 if(n) {
534 Sequence<Any> seq(1);
535 PropertyValue value;
536 value.Name = "Uri";
537 value.Handle = -1;
538 value.Value <<= m_aFTPURL.ident(false,false);
539 value.State = PropertyState_DIRECT_VALUE;
540 seq[0] <<= value;
541 ucbhelper::cancelCommandExecution(
542 IOErrorCode_UNKNOWN,
543 seq,
544 Environment);
547 else {
548 aRet <<= UnsupportedDataSinkException(
549 OUString(),
550 static_cast< cppu::OWeakObject * >(this),
551 aOpenCommand.Sink);
552 ucbhelper::cancelCommandExecution(aRet,Environment);
555 else if(aOpenCommand.Mode == OpenMode::ALL ||
556 aOpenCommand.Mode == OpenMode::DOCUMENTS ||
557 aOpenCommand.Mode == OpenMode::FOLDERS ) {
558 std::vector<FTPDirentry> resvec =
559 m_aFTPURL.list(sal_Int16(aOpenCommand.Mode));
560 Reference< XDynamicResultSet > xSet
561 = new DynamicResultSet(
562 m_xContext,
563 this,
564 aOpenCommand,
565 Environment,
566 new ResultSetFactoryI(m_xContext,
567 m_xProvider.get(),
568 aOpenCommand.Mode,
569 aOpenCommand.Properties,
570 aOpenCommand.SortingInfo,
571 resvec));
572 aRet <<= xSet;
574 else if(aOpenCommand.Mode ==
575 OpenMode::DOCUMENT_SHARE_DENY_NONE ||
576 aOpenCommand.Mode ==
577 OpenMode::DOCUMENT_SHARE_DENY_WRITE) {
578 // Unsupported OpenMode
579 aRet <<= UnsupportedOpenModeException(
580 OUString(),
581 static_cast< cppu::OWeakObject * >(this),
582 static_cast< sal_Int16 >(aOpenCommand.Mode));
583 ucbhelper::cancelCommandExecution(aRet,Environment);
585 else {
586 aRet <<= IllegalArgumentException(
587 OUString( "Unexpected OpenMode!" ),
588 static_cast< cppu::OWeakObject * >(this),
589 -1);
591 ucbhelper::cancelCommandExecution(aRet,Environment);
593 } else if(aCommand.Name == "createNewContent") {
594 ContentInfo aArg;
595 if (!(aCommand.Argument >>= aArg)) {
596 ucbhelper::cancelCommandExecution(
597 makeAny(
598 IllegalArgumentException(
599 OUString( "Wrong argument type!" ),
600 static_cast< cppu::OWeakObject * >(this),
601 -1)),
602 Environment);
603 // Unreachable
605 aRet <<= createNewContent(aArg);
606 } else {
607 aRet <<= UnsupportedCommandException(
608 aCommand.Name,
609 static_cast< cppu::OWeakObject * >(this));
610 ucbhelper::cancelCommandExecution(aRet,Environment);
613 return aRet;
615 catch(const curl_exception& e)
617 if(e.code() == CURLE_COULDNT_CONNECT)
618 action = THROWINTERACTIVECONNECT;
619 else if(e.code() == CURLE_COULDNT_RESOLVE_HOST )
620 action = THROWRESOLVENAME;
621 else if(e.code() == CURLE_FTP_USER_PASSWORD_INCORRECT ||
622 e.code() == CURLE_LOGIN_DENIED ||
623 e.code() == CURLE_BAD_PASSWORD_ENTERED ||
624 e.code() == CURLE_FTP_WEIRD_PASS_REPLY)
625 action = THROWAUTHENTICATIONREQUEST;
626 else if(e.code() == CURLE_FTP_ACCESS_DENIED)
627 action = THROWACCESSDENIED;
628 else if(e.code() == CURLE_FTP_QUOTE_ERROR)
629 action = THROWQUOTE;
630 else if(e.code() == CURLE_FTP_COULDNT_RETR_FILE)
631 action = THROWNOFILE;
632 else
633 // nothing known about the cause of the error
634 action = THROWGENERAL;
639 #define FTP_FILE "application/vnd.sun.staroffice.ftp-file"
641 #define FTP_FOLDER "application/vnd.sun.staroffice.ftp-folder"
643 Sequence<ContentInfo > SAL_CALL
644 FTPContent::queryCreatableContentsInfo( )
645 throw (RuntimeException, std::exception)
647 return queryCreatableContentsInfo_Static();
650 // static
651 Sequence<ContentInfo >
652 FTPContent::queryCreatableContentsInfo_Static( )
653 throw (RuntimeException)
655 Sequence< ContentInfo > seq(2);
657 seq[0].Type = FTP_FILE;
658 seq[0].Attributes = ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
659 | ContentInfoAttribute::KIND_DOCUMENT;
660 Sequence< Property > props( 1 );
661 props[0] = Property(
662 OUString("Title"),
664 cppu::UnoType<OUString>::get(),
665 PropertyAttribute::MAYBEVOID
666 | PropertyAttribute::BOUND );
667 seq[0].Properties = props;
669 // folder
670 seq[1].Type = FTP_FOLDER;
671 seq[1].Attributes = ContentInfoAttribute::KIND_FOLDER;
672 seq[1].Properties = props;
674 return seq;
677 Reference<XContent > SAL_CALL
678 FTPContent::createNewContent( const ContentInfo& Info )
679 throw (RuntimeException, std::exception)
681 if( Info.Type =="application/vnd.sun.staroffice.ftp-file" || Info.Type == "application/vnd.sun.staroffice.ftp-folder" )
682 return new FTPContent(m_xContext,
683 m_pFCP,
684 m_xIdentifier,Info);
685 else
686 return Reference<XContent>(0);
692 Reference<XInterface > SAL_CALL
693 FTPContent::getParent( )
694 throw (RuntimeException, std::exception)
696 Reference<XContentIdentifier>
697 xIdent(new FTPContentIdentifier(m_aFTPURL.parent(false)));
698 return Reference<XInterface>( m_xProvider->queryContent(xIdent), UNO_QUERY );
702 void SAL_CALL
703 FTPContent::setParent(const Reference<XInterface >& /*Parent*/ )
704 throw (NoSupportException,
705 RuntimeException, std::exception)
707 throw NoSupportException();
712 OUString FTPContent::getParentURL()
714 return m_aFTPURL.parent();
718 class InsertData
719 : public CurlInput {
721 public:
723 InsertData(const Reference<XInputStream>& xInputStream)
724 : m_xInputStream(xInputStream) { }
725 virtual ~InsertData() {}
727 // returns the number of bytes actually read
728 virtual sal_Int32 read(sal_Int8 *dest,sal_Int32 nBytesRequested) SAL_OVERRIDE;
730 private:
732 Reference<XInputStream> m_xInputStream;
737 sal_Int32 InsertData::read(sal_Int8 *dest,sal_Int32 nBytesRequested)
739 sal_Int32 m = 0;
741 if(m_xInputStream.is()) {
742 Sequence<sal_Int8> seq(nBytesRequested);
743 m = m_xInputStream->readBytes(seq,nBytesRequested);
744 memcpy(dest,seq.getConstArray(),m);
746 return m;
750 void FTPContent::insert(const InsertCommandArgument& aInsertCommand,
751 const Reference<XCommandEnvironment>& Env)
753 osl::MutexGuard aGuard(m_aMutex);
755 if(m_bInserted && !m_bTitleSet) {
756 MissingPropertiesException excep;
757 excep.Properties.realloc(1);
758 excep.Properties[0] = "Title";
759 Any aAny; aAny <<= excep;
760 ucbhelper::cancelCommandExecution(aAny,Env);
763 if(m_bInserted &&
764 m_aInfo.Type == FTP_FILE &&
765 !aInsertCommand.Data.is())
767 MissingInputStreamException excep;
768 Any aAny; aAny <<= excep;
769 ucbhelper::cancelCommandExecution(aAny,Env);
772 bool bReplace(aInsertCommand.ReplaceExisting);
774 retry:
775 try {
776 if(m_aInfo.Type == FTP_FILE) {
777 InsertData data(aInsertCommand.Data);
778 m_aFTPURL.insert(bReplace,&data);
779 } else if(m_aInfo.Type == FTP_FOLDER)
780 m_aFTPURL.mkdir(bReplace);
781 } catch(const curl_exception& e) {
782 if(e.code() == FILE_EXIST_DURING_INSERT ||
783 e.code() == FOLDER_EXIST_DURING_INSERT) {
784 // Deprecated, not used anymore:
785 NameClashException excep;
786 excep.Name = m_aFTPURL.child();
787 Any aAny;
788 aAny <<= excep;
789 ucbhelper::cancelCommandExecution(aAny,Env);
790 } else if(e.code() == FOLDER_MIGHT_EXIST_DURING_INSERT ||
791 e.code() == FILE_MIGHT_EXIST_DURING_INSERT) {
792 // Interact
793 Reference<XInteractionHandler> xInt;
794 if(Env.is())
795 xInt = Env->getInteractionHandler();
797 UnsupportedNameClashException excep;
798 excep.NameClash = 0; //NameClash::ERROR;
800 if(!xInt.is()) {
801 Any aAny;
802 aAny <<= excep;
803 ucbhelper::cancelCommandExecution(aAny,Env);
806 XInteractionRequestImpl* p = new XInteractionRequestImpl;
807 Reference<XInteractionRequest> req(p);
808 xInt->handle(req);
809 if(p->approved()) {
810 bReplace = true;
811 goto retry;
813 else
814 throw excep;
816 else
817 throw;
820 // May not be reached, because both mkdir and insert can throw curl-
821 // exceptions
822 m_bInserted = false;
823 inserted();
828 Reference< XRow > FTPContent::getPropertyValues(
829 const Sequence< Property >& seqProp,
830 const Reference<XCommandEnvironment>& /*environment*/
833 rtl::Reference<ucbhelper::PropertyValueSet> xRow =
834 new ucbhelper::PropertyValueSet(m_xContext);
836 FTPDirentry aDirEntry = m_aFTPURL.direntry();
838 for(sal_Int32 i = 0; i < seqProp.getLength(); ++i) {
839 const OUString& Name = seqProp[i].Name;
840 if(Name == "Title")
841 xRow->appendString(seqProp[i],aDirEntry.m_aName);
842 else if(Name == "CreatableContentsInfo")
843 xRow->appendObject(seqProp[i],
844 makeAny(queryCreatableContentsInfo()));
845 else if(aDirEntry.m_nMode != INETCOREFTP_FILEMODE_UNKNOWN) {
846 if(Name == "ContentType")
847 xRow->appendString(seqProp[i],
848 aDirEntry.m_nMode&INETCOREFTP_FILEMODE_ISDIR
849 ? OUString(FTP_FOLDER)
850 : OUString(FTP_FILE) );
851 else if(Name == "IsReadOnly")
852 xRow->appendBoolean(seqProp[i],
853 (aDirEntry.m_nMode
854 & INETCOREFTP_FILEMODE_WRITE) == 0 );
855 else if(Name == "IsDocument")
856 xRow->appendBoolean(seqProp[i],
857 (aDirEntry.m_nMode &
858 INETCOREFTP_FILEMODE_ISDIR) != INETCOREFTP_FILEMODE_ISDIR);
859 else if(Name == "IsFolder")
860 xRow->appendBoolean(seqProp[i],
861 (aDirEntry.m_nMode &
862 INETCOREFTP_FILEMODE_ISDIR) == INETCOREFTP_FILEMODE_ISDIR);
863 else if(Name == "Size")
864 xRow->appendLong(seqProp[i],
865 aDirEntry.m_nSize);
866 else if(Name == "DateCreated")
867 xRow->appendTimestamp(seqProp[i],
868 aDirEntry.m_aDate);
869 else
870 xRow->appendVoid(seqProp[i]);
871 } else
872 xRow->appendVoid(seqProp[i]);
875 return Reference<XRow>(xRow.get());
880 Sequence<Any> FTPContent::setPropertyValues(
881 const Sequence<PropertyValue>& seqPropVal)
883 Sequence<Any> ret(seqPropVal.getLength());
884 Sequence<PropertyChangeEvent > evt;
886 osl::MutexGuard aGuard(m_aMutex);
887 for(sal_Int32 i = 0; i < ret.getLength(); ++i) {
888 if ( seqPropVal[i].Name == "Title" ) {
889 OUString Title;
890 if(!(seqPropVal[i].Value >>= Title)) {
891 ret[i] <<= IllegalTypeException();
892 continue;
893 } else if(Title.isEmpty()) {
894 ret[i] <<= IllegalArgumentException();
895 continue;
898 if(m_bInserted) {
899 m_aFTPURL.child(Title);
900 m_xIdentifier =
901 new FTPContentIdentifier(m_aFTPURL.ident(false,false));
902 m_bTitleSet = true;
903 } else
904 try {
905 OUString OldTitle = m_aFTPURL.ren(Title);
906 evt.realloc(1);
907 evt[0].PropertyName = "Title";
908 evt[0].Further = false;
909 evt[0].PropertyHandle = -1;
910 evt[0].OldValue <<= OldTitle;
911 evt[0].NewValue <<= Title;
912 } catch(const curl_exception&) {
913 InteractiveIOException excep;
914 // any better possibility here?
915 // ( the error code is always CURLE_FTP_QUOTE_ERROR )
916 excep.Code = IOErrorCode_ACCESS_DENIED;
917 ret[i] <<= excep;
919 } else {
920 Sequence<Property> props =
921 getProperties(Reference<XCommandEnvironment>(0));
923 // either unknown or read-only
924 ret[i] <<= UnknownPropertyException();
925 for(sal_Int32 j = 0; j < props.getLength(); ++j)
926 if(props[j].Name == seqPropVal[i].Name) {
927 ret[i] <<= IllegalAccessException(
928 OUString( "Property is read-only!"),
929 //props[j].Attributes & PropertyAttribute::READONLY
930 // ? "Property is read-only!"
931 // : "Access denied!"),
932 static_cast< cppu::OWeakObject * >( this ));
933 break;
938 if(evt.getLength()) {
939 // title has changed
940 notifyPropertiesChange(evt);
941 (void)exchange(new FTPContentIdentifier(m_aFTPURL.ident(false,false)));
944 return ret;
947 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */